繁体   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