gpt4 book ai didi

java - Android - 为什么此服务的多个实例正在运行

转载 作者:太空宇宙 更新时间:2023-11-03 10:28:07 27 4
gpt4 key购买 nike

我已经编写了一项服务,我计划让多个应用程序使用 Messenger 与其通信。我遵循了 Android Bound Services example for messenger 中的示例.我已将该服务放入一个 Android 库项目中,所有其他 Android 项目都使用该库。

我遇到的问题是,当我绑定(bind)到该服务时,它会运行多个服务实例。每个应用程序都以下列方式绑定(bind)到服务:

// Bind to the service
bindService(new Intent(ApplicationOneActivity.this, MessengerService.class), mConnection, Context.BIND_AUTO_CREATE);

服务是:

public class MessengerService extends Service {
/** Command to the service to display a message */
public static final int MSG_SAY_HELLO = 0;
/** Command to the service to display a message from App 1 */
public static final int MSG_APP1_HELLO = 1;

public static final int MSG_APP2_HELLO = 2;

public static final int MSG_APP3_HELLO = 3;

private int[] stat = new int[3];

private Timer timer = null;

/**
* Handler of incoming messages from clients.
*/
class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SAY_HELLO:
Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show();
break;
case MSG_APP1_HELLO:
Toast.makeText(getApplicationContext(), "App One says: " + msg.arg1, Toast.LENGTH_SHORT).show();
stat[0] = msg.arg1;
break;
case MSG_APP2_HELLO:
Toast.makeText(getApplicationContext(), "App Two says: " + msg.arg1, Toast.LENGTH_SHORT).show();
stat[1] = msg.arg1;
break;
case MSG_APP3_HELLO:
Toast.makeText(getApplicationContext(), "App Three says: " + msg.arg1, Toast.LENGTH_SHORT).show();
stat[2] = msg.arg1;
break;
default:
super.handleMessage(msg);
}
}
}

/**
* Target we publish for clients to send messages to IncomingHandler.
*/
final Messenger mMessenger = new Messenger(new IncomingHandler());

/**
* When binding to the service, we return an interface to our messenger
* for sending messages to the service.
*/
@Override
public IBinder onBind(Intent intent) {
Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();

return mMessenger.getBinder();

}

@Override
public boolean onUnbind(Intent intent) {
Toast.makeText(getApplicationContext(), "unbinding", Toast.LENGTH_SHORT).show();
return super.onUnbind(intent);
}

final Handler handler = new Handler() {

public void handleMessage(Message msg) {
// Create and send a message to the service, using a supported 'what' value
ReportAsyncTask report = new ReportAsyncTask();
report.execute("");
}
};


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

if (timer == null) {
timer = new Timer();
timer.schedule(new ScheduledTaskWithHandeler(), 10000);
Toast.makeText(getApplicationContext(), "Register Timer To Report Back ", Toast.LENGTH_SHORT).show();
}
}

@Override
public void onDestroy() {
super.onDestroy();
if (timer != null) {
timer.cancel();
timer = null;
}
}

class ScheduledTaskWithHandeler extends TimerTask {

@Override
public void run() {
handler.sendEmptyMessage(0);
}
}

private class ReportAsyncTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... urls) {
String response = "";
try {
String urlParams="device=" + URLEncoder.encode(android.os.Build.MODEL, "UTF-8")
+ "&status="+URLEncoder.encode("App1 says " + stat[0] + ", App2 says " + stat[1] + ", App3 says " + stat[2],"UTF-8");
String url = "http://192.168.43.143:8080/SimpleServlet3/monitor-servlet";
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(url+"?"+urlParams);
HttpResponse httpresponse = httpclient.execute(httpget);
HttpEntity entity = httpresponse.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
int l;
byte[] tmp = new byte[2048];
while ((l = instream.read(tmp)) != -1) {
response += l;
}
}
timer.schedule(new ScheduledTaskWithHandeler(), 10000);
} catch (Exception e) {
e.printStackTrace();
}
return response;
}

@Override
protected void onPostExecute(String result) {
Toast.makeText(getApplicationContext(), "Server says " + result, Toast.LENGTH_SHORT).show();
}

}

}

每个应用程序的 list 看起来更像是:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.app1"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk android:minSdkVersion="11" />

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

<application
android:icon="@drawable/spinifex"
android:label="@string/app_name" >
<activity
android:name=".ApplicationOneActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<service
android:name="com.example.services.MessengerService"
android:process=":remote" />
</application>

</manifest>

知道我做错了什么吗? Toast 消息非常明确地表明同一服务的多个实例正在运行。我的项目结构错了吗?我不应该把服务放在一个单独的图书馆项目中吗?

最佳答案

您必须声明 <service />仅在一个 AndroidManifest 中标记,而在其他应用中,您必须通过完整的组件名称进行绑定(bind)。如:

Intent intent = new Intent();
intent.setClassName(
"com.example.app1" /* your package which contains service */,
"com.example.services.MessengerService" /* service name */
);

bindService(intent, mConnection, Context.BIND_AUTO_CREATE);

另外,当你做 android:process=":remote" ,您告诉 android 该进程对当前应用程序是私有(private)的。

关于java - Android - 为什么此服务的多个实例正在运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10024133/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com