Android AIDL:服务与活动的通信

时间:2016-08-12 09:11:05

标签: java android aidl

我尝试实施Android AIDL通信策略。 我有活动服务。 我的活动可以成功与我的服务“对话”,但反向过程似乎无效。

总而言之,由于 Activity Service 在不同的进程中运行,它们无法共享任何数据抛出IBinder接口。 因此,onServiceConnected()方法会接收AIDL接口。 此接口在服务端实现,旨在使用(称为)活动端。 我将此接口用于register()另一个AIDL。 这个新的AIDL实现了Activity-side,并通过AIDL接口称为Service-side。 它就像一个倾听者。 不幸的是,这个新的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 。 它使用 Service 启动 bounding 并不时更新视图。 它还应该在调用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...运行到runOnUiThread()
  2. 使用其他处理程序+ bindService()
  3. 延迟postDelayed()

    我的后备技术只是使用 IAidlService 并且有一个“观察者”活动端来不断检查计数器。 但我宁愿理解为什么它不起作用,以及使用AIDL的正确方法是什么。

2 个答案:

答案 0 :(得分:0)

摘要

要更改的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");
       }
    });
}

答案 1 :(得分:0)

我也是用同样的方式做的。 我可以注册活动实例。

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

DemoService.java中。

但是在调用下面的代码时

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

请您帮我一下。