簡體   English   中英

Android AIDL:服務到活動的通信

[英]Android AIDL: Service-to-Activity communication

我嘗試實現Android AIDL通信策略。 我有活動服務 我的活動可以成功地與我的服務 “交談”,但是相反的過程似乎不起作用。

總而言之,由於活動服務運行在不同的進程中,因此它們無法共享任何數據,而不會通過IBinder接口進行共享。 因此, onServiceConnected()方法將改為接收AIDL接口。 此接口在服務端實現,旨在用於(稱為)活動端。 我使用此接口register()另一個AIDL。 此新的AIDL在活動端實現,並通過AIDL接口稱為服務端。 它像一個聽眾。 不幸的是,似乎沒有調用此新AIDL的方法。

由於AndroidManifest.xml的以下行,因此該服務以自己的方式運行:

AndroidManifest.xml中

<service android:name=".DemoService" android:process=":DemoServiceProcess" />

我有2個AIDL文件,一個知道另一個。

IAidlActivity.aidl

package app.test.aidldemo;

interface IAidlActivity {
    void publish(int count);
}

IAidlService.aidl

package app.test.aidldemo;

import app.test.aidldemo.IAidlActivity;
interface IAidlService {
    void startCounter();
    void register(IAidlActivity activity);
}

該服務實現onBind()並運行負責增加計數器的處理程序

DemoService.java

package app.test.aidldemo;
import [...]
public class DemoService extends Service
{
    protected IAidlActivity aidlActivity;

    @Override
    public IBinder onBind(Intent intent)
    {
        return new IAidlService.Stub() {
            @Override
            public void startCounter() {
                DemoService.this.startJob();
            }
            @Override
            public void register(IAidlActivity activity) {
                DemoService.this.aidlActivity = activity;
            }
        };
    }

    public void startJob() {
        final Handler handler = new Handler();
        handler.post(new Runnable() {
            protected int count = 0;
            @Override
            public void run() {
                if (count < 500) {
                    count++;  // increment counter
                    try {  // then publish it to view
                        DemoService.this.aidlActivity.publish(count);  // interface, implemented activity-side
                    } catch (RemoteException e) {}
                    handler.postDelayed(this, 2000);  // 2sec.
                }
            }
        });
    }
}

活動僅包含一個TextView 它從服務開始邊界 ,並不時更新視圖。 還應該在調用publish()時更新視圖。 但這不會發生。

MainActivity.java

package app.test.aidldemo;
import [...]
public class MainActivity extends Activity {
    protected TextView view;
    protected ServiceConnection connection;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        view = new TextView(this);
        setContentView(view);
        appendToView("Let's go!");

        connection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                IAidlService aidlService = IAidlService.Stub.asInterface(service);
                appendToView("IAidlService accessed");
                IAidlActivity.Stub aidlActivity = new IAidlActivity.Stub() {
                    @Override
                    public void publish(int count) {
                        appendToView("*** Hey, new count is: " + count + "!! ***");
                    }
                };
                appendToView("IAidlActivity created");
                try {
                    aidlService.register(aidlActivity);
                    aidlService.startCounter();  // interface, implemented service-side
                }
                catch (RemoteException e) { appendToView(e.toString()); }
            }
            @Override
            public void onServiceDisconnected(ComponentName name) {}
        };

        Intent intent = new Intent(MainActivity.this, DemoService.class);
        bindService(intent, connection, Context.BIND_AUTO_CREATE);
    }

    @Override
    public void onDestroy() {
        unbindService(connection);
        super.onDestroy();
    }

    public void appendToView(String text) {
        view.append(text + "\n");
    }
}

我也嘗試一些變化,例如:

  1. 運行appendToView("*** Hey... into runOnUiThread()
  2. 延遲bindService()通過使用另一個處理器+ postDelayed()

我的后備技術是僅使用IAidlService並具有“觀察者”活動端來不斷檢查計數器。 但是我寧願理解為什么它不起作用,以及使用AIDL的正確方法是什么。

摘要

2語句更改。

DemoService.java

final Handler handler = new Handler(DemoService.this.getMainLooper());

MainActivity.java

public void appendToView(String text) {
   view.post(new Runnable() {
       @Override
       public void run() {
           view.append(text + "\n");
       }
    });
}

我以同樣的方式做。 我可以注冊活動實例。

public void register(IAidlActivity activity) {
    DemoService.this.aidlActivity = activity
}

DemoService.java

但是當調用下面的代碼時

DemoService.this.aidlActivity.publish(count)
- DemoService.this.aidlActivity is coming null.

你能幫我這個忙嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM