編輯:關於Android編程
一直以來都認為AIDL的應用離我很遙遠,甚至不知道如何去用,也就懶得去學,之前的項目中也看到過aidl文件,只是懶得去看而已,現在感覺自己真的是無藥可救了,如果只止步於學習一些UI調整的東西談何進步,不過有些東西也真是逼著去學的,要學的東西太多了,只要隔著一段時間不用的話,估計學習的東西又都忘完了,不說了,開始講正事,也算給自己留個筆記,長時間不用再回來看看。
對於AIDL有一些人(包括我自己)的淺顯概念就是:AIDL可以跨進程訪問其他應用程序,和其他應用程序通訊,那我告訴你,很多技術都可以訪問,如廣播(應用A在AndroidManifest.xml中注冊指定Action的廣播)應用B發送指定Action的廣播,A就能收到信息,這樣也能看成不同應用之間完成了通訊(但是這種通訊是單向的);還如ContentProvider,通過URI接口暴露數據給其他應用訪問;但是這種都算不上是應用之間的通訊。可能最讓人迷惑的是Android推出來了Messager,它就是完成應用之間的通訊的。那麼為什麼還要有AIDL呢,官方文檔介紹AIDL中有這麼一句話:
Note: Using AIDL is necessary only if you allow clients from different applications to access your service for IPC and want to handle multithreading in your service. If you do not need to perform concurrent IPC across different applications, you should create your interface by implementing a Binder or, if you want to perform IPC, but do not need to handle multithreading, implement your interface using a Messenger. Regardless, be sure that you understand Bound Services before implementing an AIDL.
第一句最重要,“只有當你允許來自不同的客戶端訪問你的服務並且需要處理多線程問題時你才必須使用AIDL”,其他情況下你都可以選擇其他方法,如使用Messager,也能跨進程通訊。可見AIDL是處理多線程、多客戶端並發訪問的。而Messager是單線程處理。還是官方文檔說的明白,一句話就可以理解為什麼要有AIDL。一直認為理論應與實踐相結合,這樣才利於學習,由於現在用的是android studio ,所以就用的AS開發的一個AIDL小demo。
// ICalcAIDL.aidl package com.liujc.aidlserver; // Declare any non-default types here with import statements interface ICalcAIDL { /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */ int add(int x , int y); int min(int x , int y ); }
package com.liujc.aidlserver; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; public class CalcService extends Service { private static final String TAG = "server"; public void onCreate() { Log.e(TAG, "onCreate"); } public IBinder onBind(Intent t) { Log.e(TAG, "onBind"); return mBinder; } public void onDestroy() { Log.e(TAG, "onDestroy"); super.onDestroy(); } public boolean onUnbind(Intent intent) { Log.e(TAG, "onUnbind"); return super.onUnbind(intent); } public void onRebind(Intent intent) { Log.e(TAG, "onRebind"); super.onRebind(intent); } private final ICalcAIDL.Stub mBinder = new ICalcAIDL.Stub() { @Override public int add(int x, int y) throws RemoteException { return x + y; } @Override public int min(int x, int y) throws RemoteException { return x - y; } }; }
<service android:name=".CalcService" android:process=":remote"> <intent-filter> <action android:name="com.liujc.aidlserver.CalcService"> <category android:name="android.intent.category.DEFAULT"> </category></action></intent-filter> </service>
package com.liujc.utdemo; import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.IBinder; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Toast; import com.liujc.aidlserver.ICalcAIDL; import java.util.List; public class MainActivity extends Activity { private ICalcAIDL mCalcAidl; private ServiceConnection mServiceConn = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { Log.e("client", "onServiceDisconnected"); mCalcAidl = null; } @Override public void onServiceConnected(ComponentName name, IBinder service) { Log.e("client", "onServiceConnected"); mCalcAidl = ICalcAIDL.Stub.asInterface(service); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } /** * 點擊BindService按鈕時調用 * @param view */ public void bindService(View view) { Intent intent = new Intent("com.liujc.aidlserver.CalcService"); // intent.setAction("com.liujc.aidlserver.CalcService"); final Intent eintent = new Intent(createExplicitFromImplicitIntent(this,intent)); bindService(eintent, mServiceConn, Context.BIND_AUTO_CREATE); } /** * 點擊unBindService按鈕時調用 * @param view */ public void unbindService(View view) { if (mServiceConn != null) unbindService(mServiceConn); } /** * 點擊12+12按鈕時調用 * @param view */ public void addInvoked(View view) throws Exception { if (mCalcAidl != null) { int addRes = mCalcAidl.add(12, 12); Toast.makeText(this, addRes + "", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(this, "服務器被異常殺死,請重新綁定服務端", Toast.LENGTH_SHORT) .show(); } } /** * 點擊50-12按鈕時調用 * @param view */ public void minInvoked(View view) throws Exception { if (mCalcAidl != null) { int addRes = mCalcAidl.min(58, 12); Toast.makeText(this, addRes + "", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(this, "服務端未綁定或被異常殺死,請重新綁定服務端", Toast.LENGTH_SHORT) .show(); } } public Intent createExplicitFromImplicitIntent(Context context, Intent implicitIntent) { // Retrieve all services that can match the given intent PackageManager pm = context.getPackageManager(); ListOK,今天先到這裡resolveInfo = pm.queryIntentServices(implicitIntent, 0); // Make sure only one match was found if (resolveInfo == null || resolveInfo.size() != 1) { return null; } // Get component info and create ComponentName ResolveInfo serviceInfo = resolveInfo.get(0); String packageName = serviceInfo.serviceInfo.packageName; String className = serviceInfo.serviceInfo.name; ComponentName component = new ComponentName(packageName, className); // Create a new intent. Use the old one for extras and such reuse Intent explicitIntent = new Intent(implicitIntent); // Set the component to be explicit explicitIntent.setComponent(component); return explicitIntent; } }
晚上好,現在是凌晨兩點半,然後我還在寫代碼。電腦裡播放著《凌晨兩點半》,晚上寫代碼,腦子更清醒,思路更清晰。今天聊聊屬性動畫和自定義View搭配使用,前面都講到自定義Vi
版本:1.0日期:2014.5.16版權:© 2014 kince 轉載注明出處 這一次主要說一下Android下的進度條,為什麼是它呢,因為近期被其各種美輪
demo效果增加數據: 刪除數據 修改數據 SQLite介紹SQLite,是一款輕型的數據庫,是遵守ACID的關系型數據庫管理系統,它包含在一個相對
我們都知道,類似 Activity, Fragment 有 onSaveInstanceState() 回調用來保存狀態。在Fragment裡面,利用onSaveInst