1. 程式人生 > >實現跨程序間的Ui新增更新和顯示

實現跨程序間的Ui新增更新和顯示

 

AIDL的定義

  1. aidl是Android interface definition Language 的英文縮寫,意思Android 介面定義語言。
  2. 使用aidl可以幫助我們釋出以及呼叫遠端服務,實現跨程序通訊。
  3. 將服務的aidl放到對應的src目錄,工程的gen目錄會生成相應的介面類

 

 RemoteViews執行流程:

  1. RemoteViews通過Binder傳遞至SystemServer程序(因為RemoteViews實現了Parcelable介面,因此它可以跨程序傳輸)
  2. 系統根據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;
            }
        }
    }