我尝试实施Android AIDL通信策略。 我有活动和服务。 我的活动可以成功与我的服务“对话”,但反向过程似乎无效。
总而言之,由于 Activity 和 Service 在不同的进程中运行,它们无法共享任何数据抛出IBinder
接口。
因此,onServiceConnected()
方法会接收AIDL接口。
此接口在服务端实现,旨在使用(称为)活动端。
我将此接口用于register()
另一个AIDL。
这个新的AIDL实现了Activity-side,并通过AIDL接口称为Service-side。
它就像一个倾听者。
不幸的是,这个新的AIDL的方法似乎没有被调用。
由于AndroidManifest.xml
中的以下行,服务在其自己的流程中运行:
<service android:name=".DemoService" android:process=":DemoServiceProcess" />
我有2个AIDL文件,一个知道另一个。
package app.test.aidldemo;
interface IAidlActivity {
void publish(int count);
}
package app.test.aidldemo;
import app.test.aidldemo.IAidlActivity;
interface IAidlService {
void startCounter();
void register(IAidlActivity activity);
}
服务实现onBind()
并运行处理程序,负责增加计数器。
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()
时更新视图。
但这不会发生。
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");
}
}
我也尝试了一些变体:
appendToView("*** Hey...
运行到runOnUiThread()
bindService()
postDelayed()
醇>
我的后备技术只是使用 IAidlService 并且有一个“观察者”活动端来不断检查计数器。 但我宁愿理解为什么它不起作用,以及使用AIDL的正确方法是什么。
答案 0 :(得分:0)
要更改的2条陈述。
final Handler handler = new Handler(DemoService.this.getMainLooper());
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.
请您帮我一下。