gpt4 book ai didi

java - 服务重启后出现 DeadObjectException

转载 作者:行者123 更新时间:2023-12-01 09:09:44 25 4
gpt4 key购买 nike

我有一个 Activity ,其中使用 startService() 启动服务,并在 onStart() 方法中绑定(bind)到同一服务。我使用 Messenger 发送一些文本来提供服务,然后将服务打开套接字发送到该文本所在的服务器,然后服务器用一些文本进行响应(这工作正常)。当我尝试使用信使将服务的响应发送到 Activity 时,就会出现问题。当应用程序第一次启动时,即使工作正常,但在应用程序被终止(因此服务重新启动)并且我尝试将服务的响应发送到 Activity 时,我得到DeadObjectException。我评论了服务中发生错误的行。

这是我的 Activity :

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {

private GoogleMap mMap;
TextView tvFromServer;
EditText etSend;
Button bSend, bStopSocket, bBound, bStopService;
boolean mRun;
Intent mIntent;

/** Messenger for communicating with the service. */
Messenger mService = null;
/** Flag indicating whether we have called bind on the service. */
boolean mBound;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
//SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
// .findFragmentById(R.id.map);
//mapFragment.getMapAsync(this);

initialize();
mIntent = new Intent(this, SocketService.class);
startService(mIntent);

}

@Override
protected void onStart() {
super.onStart();

Intent iBind = new Intent(this, SocketService.class);
iBind.putExtra("messenger", new Messenger(mHandler));
bindService(iBind, mConnection, Context.BIND_AUTO_CREATE);
}

@Override
protected void onStop() {
super.onStop();
// Unbind from the service
if (mBound) {
unbindService(mConnection);
mBound = false;
mConnection = null;
mHandler = null;
}
}

Handler mHandler = new Handler(Looper.getMainLooper()){
@Override
public void handleMessage(Message msg) {
//Log.v("MapsActivity", (String) msg.obj );(String) msg.obj
tvFromServer.setText(msg.getData().getString("text"));
}
};

/**
* Class for interacting with the main interface of the service.
*/
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
// This is called when the connection with the service has been
// established, giving us the object we can use to
// interact with the service. We are communicating with the
// service using a Messenger, so here we get a client-side
// representation of that from the raw IBinder object.
mService = new Messenger(service);
mBound = true;
}

public void onServiceDisconnected(ComponentName className) {
// This is called when the connection with the service has been
// unexpectedly disconnected -- that is, its process crashed.
mService = null;
mBound = false;
}
};


private void initialize(){
tvFromServer = (TextView) findViewById(R.id.tv_from_server);
bStopSocket = (Button) findViewById(R.id.b_stop);
mRun = false;
bStopSocket.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mRun = false;
}
});

etSend = (EditText) findViewById(R.id.et_send);
bSend = (Button) findViewById(R.id.b_send);
bSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!mBound) return;
Message msg = Message.obtain(null, 1, etSend.getText().toString());
try {
mService.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
});

bBound = (Button) findViewById(R.id.b_bound);
bBound.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!mBound) return;
Message msg = Message.obtain(null, 1, "Hello from Activity");
try {
mService.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}

}
});
bStopService = (Button) findViewById(R.id.b_stop_service);
bStopService.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mBound) {
unbindService(mConnection);
mBound = false;
}
stopService(mIntent);
}
});
}


/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
@Override
public void onMapReady(GoogleMap googleMap) {
//mMap = googleMap;

// Add a marker in Sydney and move the camera
//LatLng sydney = new LatLng(-34, 151);
//mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
//mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
}

}

服务:

public class SocketService extends Service {
public SocketService() {
}

private Looper mServiceLooper;
private ServiceHandler mServiceHandler;
public Messenger mMessenger, mUiMessenger;
PrintWriter out;
Socket mSocket;
boolean mRun;
Thread threa;


// Handler that receives messages from the thread
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
// Normally we would do some work here, like download a file.
// For our sample, we just sleep for 5 seconds.
if(msg.what == 1){
out.println((String) msg.obj);
}

}
}

@Override
public void onCreate() {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
// Start up the thread running the service. Note that we create a
// separate thread because the service normally runs in the process's
// main thread, which we don't want to block. We also make it
// background priority so CPU-intensive work will not disrupt our UI.
HandlerThread thread = new HandlerThread("SocketService");
thread.start();

// Get the HandlerThread's Looper and use it for our Handler
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
mMessenger = new Messenger(new ServiceHandler(mServiceLooper));
mRun = false;

threa = new Thread(new Runnable() {
@Override
public void run() {
socketConnection();

}
});
threa.start();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
mServiceHandler.sendMessage(msg);
return START_STICKY;
}

@Override
public IBinder onBind(Intent intent) {
Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();
Bundle extras = intent.getExtras();
mUiMessenger = (Messenger) extras.get("messenger");
return mMessenger.getBinder();
}

@Override
public void onDestroy() {
Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();

}

private void socketConnection() {
mRun = true;
try{
mSocket = new Socket("xxx.xxx.xxx.xxx", xxxxx);
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(mSocket.getOutputStream())), true);
BufferedReader in = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));

while(mRun){
String s = in.readLine();
Log.v("SocketServiceFromServer", s);
Bundle bundle = new Bundle();
bundle.putString("text", s);
Message msg = Message.obtain(null, 1);
msg.setData(bundle);
try {
mUiMessenger.send(msg); //DeadObjectException is thrown here after service is restarted
} catch (RemoteException e) {
e.printStackTrace();
}
}
mSocket.close();
}catch(Exception e){
Log.e("SocketService ", e.toString());
}
}
}

日志猫:

![logcat

我的问题是,为什么会抛出这个错误?看起来 Activity 在重新启动后绑定(bind)到服务时不会向服务发送新的信使对象。

最佳答案

我遇到了完全相同的问题,并且找到了解决方案。我花了 4 个小时来调试代码、搜索互联网并尝试了数百万种不同的方法。解决办法很简单。删除 onCreate 中调用 startService。仅使用bindService 和unbindService。是的,就是这么简单...

关于java - 服务重启后出现 DeadObjectException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40994627/

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