通過AIDL實現跨進程更新UI

来源:https://www.cnblogs.com/ganchuanpu/archive/2018/04/17/8867105.html
-Advertisement-
Play Games

一、概述 本篇文章將和大家一起來學習AIDL實現跨進程更新UI。 需求是:在同一個應用中有兩個Activity,MainActivity和TempActivity,這兩個Activity不在同一個進程中。 現在需要通過TempActivity來改變MainActivity中的視圖,即修改MainAc ...


一、概述

本篇文章將和大家一起來學習AIDL實現跨進程更新UI。 
需求是:在同一個應用中有兩個Activity,MainActivity和TempActivity,這兩個Activity不在同一個進程中。

這裡寫圖片描述

現在需要通過TempActivity來改變MainActivity中的視圖,即修改MainActivity中TextView的顯示內容並且添加兩個Button,也就是實現跨進程更新UI這麼一個功能。

對於這種跨進程更新UI的需求我們可以通過AIDL或者BroadcastReceiver的方式實現,而本篇文章主要通過AIDL的方式實現,如果你對AIDL 
還不熟悉的話可以先看看我的這篇文章:

二、實現效果圖

在MainActivity里點擊“跳轉到新進程ACTIVITY”按鈕,會啟動一個新進程的TempActivity,我們先點擊“綁定服務”,這樣我們就啟動了服務,再點擊“AIDL更新”按鈕,通過調用handler來實現跨進程更新UI,點擊返回,我們發現MainActivity頁面中的TextView內容已經更新了,並且新添加了兩個按鈕。 
這裡寫圖片描述

三、核心代碼

IViewManager.aidl 
裡面提供了兩個方法,一個是根據id更新TextView裡面的內容,一個是根據id添加view視圖

// IViewManager.aidl
package com.czhappy.remoteviewdemo;

// Declare any non-default types here with import statements

interface IViewManager {
    void setTextViewText(in int id,in String text);//設置TextView的內容
    void addView(in int layoutId);                 //添加View視圖
}

rebuild project讓IDE工具自己生成AIDL介面對應的java文件。

ViewAIDLService.java

package com.czhappy.remoteviewdemo.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.util.Log;

import com.czhappy.remoteviewdemo.IViewManager;
import com.czhappy.remoteviewdemo.activity.MainActivity;

public class ViewAIDLService extends Service {
    private static final String TAG = "ViewAIDLService";
    private Binder viewManager = new IViewManager.Stub(){
        @Override
        public void setTextViewText(int id, String text) throws RemoteException {
            Message message = new Message();
            message.what = 2;
            Bundle bundle = new Bundle();
            bundle.putInt("id",id);
            bundle.putString("text",text);
            message.setData(bundle);
            new MainActivity.MyHandler(ViewAIDLService.this,getMainLooper()).sendMessage(message);
        }

        @Override
        public void addView(int layoutId) throws RemoteException {
            Message message = new Message();
            message.what = 3;
            Bundle bundle = new Bundle();
            bundle.putInt("layoutId",layoutId);
            message.setData(bundle);
            Log.i(TAG,"thread name = "+Thread.currentThread().getName());
            new MainActivity.MyHandler(ViewAIDLService.this,getMainLooper()).sendMessage(message);
        }

    };
    public ViewAIDLService() {
    }

    /**
     * 當客戶端綁定到該服務時調用
     * @param intent
     * @return
     */
    @Override
    public IBinder onBind(Intent intent) {
        return viewManager;
    }
}

MainActivity.java

package com.czhappy.remoteviewdemo.activity;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.RemoteViews;
import android.widget.TextView;

import com.czhappy.remoteviewdemo.R;

import java.lang.ref.WeakReference;

public class MainActivity extends AppCompatActivity {

    private static String TAG = "MainActivity";
    private static LinearLayout mLinearLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mLinearLayout = (LinearLayout) this.findViewById(R.id.mylayout);
    }

    public static class MyHandler extends Handler {
        WeakReference<Context> weakReference;
        public MyHandler(Context context, Looper looper) {
            super(looper);
            weakReference = new WeakReference<>(context);
        }
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Log.i(TAG, "handleMessage");
            switch (msg.what) {
                case 2: //修改MainActivity中TextView的內容
                    Bundle bundle = msg.getData();
                    TextView textView = (TextView) mLinearLayout.findViewById(bundle.getInt("id"));
                    textView.setText(bundle.getString("text"));
                    break;
                case 3: //在MainActivity中添加View視圖
                    LayoutInflater inflater = LayoutInflater.from(weakReference.get());
                    View view = inflater.inflate(msg.getData().getInt("layoutId"),null);
                    mLinearLayout.addView(view);
                default:
                    break;
            }
        }

    };

    public void readyGo(View view){
        Intent intent = new Intent(MainActivity.this, TempActivity.class);
        startActivity(intent);
    }

}

TempActivity.java

package com.czhappy.remoteviewdemo.activity;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;

import com.czhappy.remoteviewdemo.IViewManager;
import com.czhappy.remoteviewdemo.R;
import com.czhappy.remoteviewdemo.service.ViewAIDLService;

public class TempActivity extends AppCompatActivity {

    private String TAG = "TempActivity";

    private IViewManager viewsManager;
    private boolean isBind = false;


    private ServiceConnection viewServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.e(TAG,"onServiceConnected");
            viewsManager = IViewManager.Stub.asInterface(service);

        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            //回收
            viewsManager = null;
        }
    };

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.setContentView(R.layout.activity_temp);
    }

    /**
     * 綁定服務
     */
    public void bindService(View view) {
        Intent viewServiceIntent = new Intent(this,ViewAIDLService.class);
        isBind = bindService(viewServiceIntent,viewServiceConnection, Context.BIND_AUTO_CREATE);
    }

    /**
     * 更新UI
     */
    public void UpdateUI(View view){
        try {
            viewsManager.setTextViewText(R.id.mytext,"通過AIDL跨進程修改TextView內容");
            viewsManager.addView(R.layout.button_layout);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(isBind){
            unbindService(viewServiceConnection);
            isBind = false;
        }

    }

}

配置文件AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.czhappy.remoteviewdemo">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".activity.MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".activity.TempActivity"
            android:process=":remote">
        </activity>

        <service android:name="com.czhappy.remoteviewdemo.service.ViewAIDLService"/>

    </application>

</manifest>

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 開發文檔 官方開發文檔 開發IDE 官方工具下載 UI組件 WeUI:是一套同微信原生視覺體驗一致的基礎樣式庫,由微信官方設計團隊為微信內網頁和微信小程式量身設計; ZanUI-WeApp:是有贊移動 Web UI 規範 ZanUI 的小程式現實版本,結合了微信的視覺規範 MinUI:是基於微信小程 ...
  • 需要:pod 'YYKit' 在block語句塊中,如果需引用self,而self對象中又持有block對象,就會造成迴圈引用迴圈引用(retain cycle),導致記憶體泄露,比如以下代碼 一般我們是這麼解決的,使用一個__weal修飾的weakSelf變數指向self對象,在block中使用we ...
  • 使用最廣泛的解析XML文檔的方法有兩種,一種基於SAX,另一種基於DOM。SAX解析器是事件驅動型的,在解析時增量地讀取XML文檔,當解析器識別出一個結點的時候會調用相應的委托方法。 參考資料《iOS編程指南》 ...
  • 安卓使用的資料庫是sqlite 創建方式:新建一個類繼承SQLiteOpenHelper 這裡第二個參數:資料庫的名字,第三個參數為結果集(游標)寫成null即可,最後一個參數為資料庫的版本,寫1即可 在MainActivity中新建實例即可創建資料庫: 好的,運行即可創建資料庫成功 接下來看下My ...
  • The Apple Developer Program License Agreement has been updated. In order to access certain membership resources, you must accept the latest license ag ...
  • 本文從攻防原理層面解析了iOS APP的安全策略。iOS以高安全性著稱,但它並非金剛不壞之身。對於信息安全而言,止大風於青萍之末是上上策,杭研深入各個細節的研發工作,正是網易產品質量的保障。 一、iOS的安全問題 世所公認,iOS系統安全性非常高,很少出現漏洞,幾乎不會中毒的情況。然而隨著各種iOS ...
  • 生成XML的方式: 第一種:利用StringBuffer強行拼接 第二種:通過XmlSerializer方式(推薦) 下邊是示例: 一個簡單的界面: 一個Javabean: 看一下生成的XML: 成功! ...
  • 1.transform屬性 在iOS開發中,通過transform屬性可以修改UIView對象的平移、縮放比例和旋轉角度,常用的創建transform結構體方法分兩大類 (1) 創建“基於控制項初始位置”的形變 CGAffineTransformMakeTranslation(平移) CGAffine ...
一周排行
    -Advertisement-
    Play Games
  • 前言:有時候遠程伺服器的進程你想偷偷去圍觀一下有哪些,或者對一些比較調皮的進程進行封殺,或者對一些自己研發的服務進行遠程手動啟動或者重啟等,又不想打開遠程桌面,只想悄咪咪地執行,那也許下麵的文章會對你有啟發。 前提條件 確保遠程伺服器(服務端)已啟用WinRM。在遠程伺服器上運行以下命令可以啟用和配 ...
  • 爆了,爆了,DeveloperSharp系列近期又被製造業ERP、民航飛行App、建築BIM、電力掌上營業廳、等多家大型採用,站在巨人的肩膀上你能走的更遠。 支持.Net Core2.0及以上,支持.Net Framework4.0及以上 http請求調用是開發中經常會用到的功能。在內,調用自有項目 ...
  • StackExchange.Redis 是一個高性能的 Redis 客戶端庫,主要用於 .NET 環境下與 Redis 伺服器進行通信,大名鼎鼎的stackoverflow 網站就使用它。它使用非同步編程模型,能夠高效處理大量請求。支持 Redis 的絕大部分功能,包括發佈/訂閱、事務、Lua 腳本等... ...
  • 一:背景 1. 講故事 前些天群里有一個朋友說他們軟體會偶發崩潰,想分析看看是怎麼回事,所幸的是自己會抓dump文件,有了dump就比較好分析了,接下來我們開始吧。 二:WinDbg 分析 1. 程式為什麼會崩潰 windbg 還是非常強大的,當你雙擊打開的時候會自動幫你定位過去展示崩潰時刻的寄存器 ...
  • 工廠模式(Factory Pattern)是一種創建型設計模式,它提供了一種創建對象的介面,而不是通過具體類來實例化對象。工廠模式可以將對象的創建過程封裝起來,使代碼更具有靈活性和可擴展性。 工廠模式有幾種常見的實現方式: 簡單工廠模式(Simple Factory Pattern): 簡單工廠模式 ...
  • Web Service 理解:Web Service 是一種基於網路的服務,它使用標準化的消息傳遞協議,最典型的是基於 SOAP(Simple Object Access Protocol)協議。SOAP 使用 XML 格式封裝數據,定義了消息的結構和傳輸方式,因此它是一個重量級的解決方案。Web ...
  • 可以使用XmlSerializer直接序列化和反序列化xml 反序列化如以下代碼 private T? XmlDeseriallize<T>(string filePath) { XmlSerializer serializer = new XmlSerializer(typeof(T)); usi ...
  • 不管是在控制台程式還是asp.net core程式中,我們經常會有用到一個需要長時間運行的後臺任務的需求。通常最直覺的方式是使用Thread實例來新建一個線程,但是這樣需要自行管理線程的啟動和停止。 在.net core中提供了一個繼承自IHostedService的基類BackgroudServi ...
  • 最近YOLO家族又添新成員:YOLOv10,YOLOv10 提出了一種一致的雙任務方法,用於無nms訓練的YOLOs,它同時帶來了具有競爭力的性能和較低的推理延遲。此外,還介紹了整體效率-精度驅動的模型設計策略,從效率和精度兩個角度對YOLOs的各個組成部分進行了全面優化,大大降低了計算開銷,增強了... ...
  • 自動篩選器是 Excel 中的一個基本但極其有用的功能,它可以讓你根據特定的條件來自動隱藏和顯示你的數據。當有大量的數據需要處理時,這個功能可以幫你快速找到你需要的信息,從未更加有效地分析和處理相關數據。 下麵將介紹如何使用免費.NET Excel庫在Excel中添加、應用和刪除自動篩選器。包含以下 ...