實現跨程序間的Ui新增更新和顯示
阿新 • • 發佈:2018-11-22
AIDL的定義
- aidl是Android interface definition Language 的英文縮寫,意思Android 介面定義語言。
- 使用aidl可以幫助我們釋出以及呼叫遠端服務,實現跨程序通訊。
- 將服務的aidl放到對應的src目錄,工程的gen目錄會生成相應的介面類
RemoteViews執行流程:
- RemoteViews通過Binder傳遞至SystemServer程序(因為RemoteViews實現了Parcelable介面,因此它可以跨程序傳輸)
- 系統根據RemoteViews中的packageName, layoutId去得到該應用的資源,之後通過LayoutInflater去載入RemoteViews中的佈局檔案
先定義一個IRemoteViewsManager.aidl檔案,rebuild會自動生成對應的java檔案
// IRemoteViewsManager.aidl
package com.kawa.qkplug;
// Declare any non-default types here with import statements
interface IRemoteViewsManager {
void addRemoteView(in RemoteViews remoteViews);
void isShowView();
}
之後設定服務進行監聽,通過回撥進行相應程序的Ui處理
package com.kawa.qkplug.service; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.Bundle; import android.os.IBinder; import android.os.Message; import android.os.RemoteException; import android.widget.RemoteViews; import com.kawa.qkplug.IRemoteViewsManager; import com.kawa.qkplug.ui.MainActivity; public class RemoteAIDLService extends Service { private Binder remoteViewBinder = new IRemoteViewsManager.Stub() { @Override public void addRemoteView(RemoteViews remoteViews) throws RemoteException { Message message = new Message(); message.what = 1; Bundle bundle = new Bundle(); bundle.putParcelable("remoteViews", remoteViews); message.setData(bundle); new MainActivity.ViewHandler(RemoteAIDLService.this, getMainLooper()).sendMessage(message); } @Override public void isShowView() throws RemoteException { Message message = new Message(); message.what = 4; new MainActivity.ViewHandler(RemoteAIDLService.this, getMainLooper()).sendMessage(message); } }; public RemoteAIDLService() { } @Override public IBinder onBind(Intent intent) { return remoteViewBinder; } }
繫結服務方式:
Intent viewService = new Intent(this, ViewAIDLService.class);
bindService(viewService, serviceConnection2, Context.BIND_AUTO_CREATE);
監聽服務的連線狀態
private ServiceConnection serviceConnection2 = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
remoteViewsManager = IRemoteViewsManager.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
remoteViewsManager = null;
}
};
處理Ui的新增更新顯示
RemoteViews remoteViews = new RemoteViews(this.getPackageName(),R.layout.wg_button);
Intent intentClick = new Intent(TestAidlActivity.this,TestAidlActivity.class);
PendingIntent openMainActivity = PendingIntent.getActivity(TestAidlActivity.this,0,intentClick,0);
remoteViews.setOnClickPendingIntent(R.id.text,openMainActivity);
remoteViews.setCharSequence(R.id.text,"setText","two two");
try {
remoteViewsManager.addRemoteView(remoteViews);
remoteViewsManager.isShowView();
} catch (RemoteException e) {
e.printStackTrace();
}
UI更新處理頁面:
public static class ViewHandler extends Handler {
WeakReference<Context> weakReference;
public ViewHandler(Context context, Looper looper) {
super(looper);
weakReference = new WeakReference<>(context);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:
RemoteViews remoteViews = msg.getData().getParcelable("remoteViews");
if (remoteViews != null) {
Log.e("kawa", "更新Ui");
View view = remoteViews.apply(weakReference.get(), mLayout);
mLayout.addView(view);
}
break;
case 4:
mTextTip.setVisibility(mTextTip.getVisibility() == View.GONE ? View.VISIBLE : View.GONE);
break;
}
}
}