1. 程式人生 > >Android中Service與Activity資料互動的簡單理解

Android中Service與Activity資料互動的簡單理解

Service跟Activity是最相似的元件,都代表可執行的程式,區別在於:Service一直在後臺執行,沒有跟使用者互動的介面。
啟動與停止Service有兩種方法:
第一種通過startService()與stopService()啟動和停止服務,Service與啟動它的Activity無法進行通訊和資料交換
第二種通過bindService()與unbindService()啟動和停止服務。在啟動時,通過bindService(Intent, ServiceConnection, int)啟動服務,unbindService(ServiceConnection) 停止服務。
啟動ServiceConnection引數為互動資料的物件:
首先在Activity中

// 宣告IBinder物件
private BindService.MyBinder binder;
private ServiceConnection sc = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            // 這裡的引數service就是互動的資料
            binder = (BindService.MyBinder) service;
        }

        @Override
public void onServiceDisconnected(ComponentName name) { } };

所以需要在Service類定義時定義一個Binder物件,在Service類中的onBind方法中返回:

// 定義MyBind物件
private MyBinder binder = new MyBinder();
public class MyBinder extends Binder{
    // 這在裡面可以返回跟Activity互動的資料
    // 可以是基本型別,String,以及經過序列化的物件
}
@Override
public IBinder onBind(Intent intent) { return binder; }

這樣就能完成Service與Activity資料互動的任務了。

以上是同進程間Service與Activity的互動。下面說一下不同程序Activity與Service之間的互動,最簡單的IPC機制
大致的流程是,客戶端即Activity傳送一個資訊到服務端Service,服務端Service收到訊息後進行響應。客戶端與服務端通訊的機制是通過Handler來實現的。
首先,我們要定義一個類MessagerHandler繼承Handler,通過handler來進行訊息傳遞,之後我們需要宣告一個信使Messenger,通過信使來傳遞資訊。
服務端MessengerService具體程式碼如下

public class MessengerService extends Service{

    private static final String TAG = "MessengerService";

    public static final int MSG_FROM_CLIENT = 0;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mMessenger.getBinder();
    }

    private static class MessagerHandler extends Handler{
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case MSG_FROM_CLIENT:
                    Log.i(TAG, "receive msg from Client:" + msg.getData().getString("msg"));

                    // 收到訊息後回傳給客戶端
                    Messenger client = msg.replyTo;
                    Message replyMessage = Message.obtain(null, MSG_FROM_CLIENT);
                    Bundle bundle = new Bundle();
                    bundle.putString("reply", "嗯,你的訊息我哦已經收到了.");
                    replyMessage.setData(bundle);
                    try {
                        client.send(replyMessage);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                    break;
                default:
                    super.handleMessage(msg);
                    break;
            }
        }
    }

    private final Messenger mMessenger = new Messenger(new MessagerHandler());


}

下面來寫客戶端MainActivity,客戶端與服務端是通過ServiceConnection物件進行連線的,首先定義mConnection物件,在onServiceConnected方法中獲取到Binder,然後通過Message將資訊發出去,最後仍然是通過信使Messenger來獲取伺服器返回的資訊。具體程式碼如下

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

    private Messenger mService;

    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mService = new Messenger(service);
            Message msg = Message.obtain(null, MessengerService.MSG_FROM_CLIENT);
            Bundle data = new Bundle();
            data.putString("msg", "hello, this is client.");
            msg.setData(data);

            // 傳送目標
            msg.replyTo = mGetReplyMessenger;
            try {
                mService.send(msg);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        Intent intent = new Intent(this, MessengerService.class);
        bindService(intent, mConnection, BIND_AUTO_CREATE);

    }

    private Messenger mGetReplyMessenger = new Messenger(new MessengerHandler());

    private static class MessengerHandler extends Handler{
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case MessengerService.MSG_FROM_CLIENT:
                    Log.i(TAG, "receive msg from Service:" + msg.getData().getString("reply"));
                    break;
                default:
                    super.handleMessage(msg);
                    break;
            }

        }
    }

    @Override
    protected void onDestroy() {
        unbindService(mConnection);
        super.onDestroy();
    }
}

以上就是IPC機制通過Binder來進行通訊,這是單條資訊處理的機制,如果需要進行多資訊的互動,就需要更復雜的操作。

相關推薦

AndroidServiceActivity資料互動簡單理解

Service跟Activity是最相似的元件,都代表可執行的程式,區別在於:Service一直在後臺執行,沒有跟使用者互動的介面。 啟動與停止Service有兩種方法: 第一種通過startService()與stopService()啟動和停止服務,Se

AndroidServiceActivity的通訊---回撥介面方式

最近在技術交流群中有人問到:要實現service與activity的高強度通訊用什麼方法? 群友回答的是用handler,但面試官好像不太滿意,後來本人查找了下資料,得到個人的結論:service與activity之前的通訊方式有很多,回撥介面方式、觀察者模式、廣播、還有h

Android ServiceActivity互動

Android中有時候需要在Service中改變Activity的UI,或者在Activity中修改Service中的數值。首先必須使用與Activity繫結的Service,有三種方式可以實現。第一,是使用介面回撥的方式在Activty中實現Service中的介面;第二,使用廣播的方式傳遞;第三,則是用觀察

androidWebviewjavascript的互動(互相呼叫)

最近做android專案中遇到要在webview中做與js互動相關的東東,涉及到js中呼叫android本地的方法,於是查了資料整理了一下android和js互相呼叫的過程。如下demo,demo的主要實現過程如下:通過載入本地的html檔案(裡面有js指令碼),實現and

AndroidWebview原生介面互動及二維碼掃描功能實現

最近專案中有一個新的需求,大致是這樣的:APP中通過WebView展示一個第三方的HTML5介面,使用者可以在HTML5介面中呼叫Android攝像頭進行二維碼掃描,並將掃描結果顯示在HTML5介面。這顯然涉及到了Android原生與WebView之前的傳值

Android ServiceActivity之間傳值。(涉及BroadCast的基本用法)

首先先建立一個Android工程(名字自定義)這裡我命名為MyActivity 包名為:package org.hm.myactivity; 再最後給自己的activity命名(名字自定義)此處我命名為MyTestActivity public class MyTestA

androidfragmentactivity之間通訊原理以及例子

首先,如果你想在android3.0及以下版本使用fragment,你必須引用android-support-v4.jar這個包 然後你寫的activity不能再繼承自Activity類了,而是要繼承android.support.v4.app.FragmentA

android客戶端servlet伺服器互動簡單示例

前段時間需要寫一個能雙向解析XML的程式,但是客戶端只能從伺服器裡讀,但是死活傳不上去,倒騰了兩天終於搞好了。 下面直接貼示例程式碼,不明白的話再問吧。 這是android客戶端,記得得在AndroidManifest.xml檔案裡新增INTENET許可權。 publ

Android實現FragmentActivity之間的資料互動

1概念 1 為什麼 因為Fragment和Activity一樣是具有生命週期,不是一般的bean通過建構函式傳值,會造成異常。 2 參考連結 Activity和Fragment傳遞資料的兩種方式 【Fragment精深系列4】Frag

Android兩個Activity之間簡單通信

idg tin test ide button ima 接收 9.png set 在Android中,一個界面被稱為一個activity,在兩個界面之間通信,采用的是使用一個中間傳話者(即Intent類)的模式,而不是直接通信。 下面演示如何實現兩個activity之間的通

關於android 同時在activity啟動Service

同時在Activity中的onCreate();中呼叫startService(); bindService();Service的生命週期 這個截圖,我是先用startService(),接著bindService();

轉:AndroidIntentServiceService的區別

https://blog.csdn.net/matrix_xu/article/details/7974393 Android中的Service是用於後臺服務的,當應用程式被掛到後臺的時候,問了保證應用某些元件仍然可以工作而引入了Service這個概念,那麼這裡面要強調的是Service不是獨立

Android 介面卡fragment或者activity的回撥使用

如何使用介面回撥       使用場景:在activity或者fragment與adapter的回撥中        介面卡中使用: public OnUpdat

Android ServiceActivity的交互

create ces per andro 時機 子線程 lse tag ins Android中有時候需要在Service中改變Activity的UI,或者在Activity中修改Service中的數值。首先必須使用與Activity綁定的Service,有三種方式可以實現

AndroidWebviewjs互動

1.js呼叫Android程式碼Android端:webView.addJavascriptInterface(new WebHost(this),"js");向WebView註冊一個名叫“js”的物件,然後在JS中可以訪問js這個物件,呼叫這個物件裡的一些方法。 publi

Androidwifi資料流量的切換監聽

最近在做一個wifi和移動資料的監控功能,來來回回折騰了一陣子,這個模組的主要功能是監聽整個APP的wifi與資料流量的切換,讓使用者使用專用流量,而不是用wifi,給一個彈窗,點選確認,自動切換資

Struts2的後臺前臺資料互動處理方式的簡單總結

 4種拿到值得的辦法: 1)  <s:property value="username"/> 2) {username}    3) <s:property value="#request.username"/>  4) <s:property value="%{username

Android實現登入功能,Android伺服器資料互動,使用tomcat、mysql實現登入的demo程式,web端和android均可實現登入

1.使用到的開發工具為:Eclipse(Java EE),Android Studio,MYSQL 5.7.21;2.首先在MYSQL資料庫建表,我這裡使用的資料庫視覺化操作軟體為:navicat premium:如圖:這裡你可以取自己喜歡的資料庫名字,但是為了方便起見,我建

linuxservicechkconfig的替代者systemctl的簡單介紹

linux中有很多命令已經存在了N多年,漸漸一些已被一些新命令所代替,不過由於習慣的原因,很多時候我們並不能一下子適應過來 ,例如ifconfig之於ip命令。 最近在升級到centos7時也發現不支援service命令了,systemctl是systemd下

Android ServiceActivity之間通訊:通過Binder物件、Broadcast廣播

From:http://blog.csdn.net/xiaanming/article/details/9750689 From:http://blog.csdn.net/ameyume/article/details/6290137 From:http://blog.c