[英]Android AIDL: Service-to-Activity communication
我嘗試實現Android AIDL通信策略。 我有活動和服務 。 我的活動可以成功地與我的服務 “交談”,但是相反的過程似乎不起作用。
總而言之,由於活動和服務運行在不同的進程中,因此它們無法共享任何數據,而不會通過IBinder
接口進行共享。 因此, onServiceConnected()
方法將改為接收AIDL接口。 此接口在服務端實現,旨在用於(稱為)活動端。 我使用此接口來register()
另一個AIDL。 此新的AIDL在活動端實現,並通過AIDL接口稱為服務端。 它像一個聽眾。 不幸的是,似乎沒有調用此新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 。 它從服務開始邊界 ,並不時更新視圖。 還應該在調用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...
into runOnUiThread()
bindService()
通過使用另一個處理器+ postDelayed()
我的后備技術是僅使用IAidlService並具有“觀察者”活動端來不斷檢查計數器。 但是我寧願理解為什么它不起作用,以及使用AIDL的正確方法是什么。
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");
}
});
}
我以同樣的方式做。 我可以注冊活動實例。
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.