我有一个启动并绑定(bind)到 Service
的 Activity
。然后我有另一个 Activity
,从第一个开始。从第二个返回到第一个 Activity
后,我需要调用 Service
的一个方法(保存一些数据)。
在查看每个 Activity
时,我的 Activity
生命周期方法似乎可以充分应对屏幕方向的变化,前提是我在退出 Activity 之前返回到相同的屏幕方向
。
当我以与离开时不同的方向返回到第一个 Activity 时,就会出现问题。如果发生这种情况,我将失去对我的 Service
的引用,并因此在 onActivityResult()
中遇到 NullPointerException
。因此,如果我以纵向模式启动第二个 Activity
,在查看第二个 Activity
时切换到横向,然后以横向模式返回到第一个 Activity
,它会崩溃。
我可能遗漏了什么?我不想使用 list 文件来指示我将处理配置更改——我觉得这是一个有点丑陋的 hack,它没有解决主要问题。除非我又遗漏了什么...
以下是第一个 Activity 的生命周期方法的摘录:
@Override
protected void onStart()
{
super.onStart();
// start and bind to service
startService(smsIntent);
connection = new SMServiceConnection();
bindService(smsIntent, connection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onRestart()
{
super.onRestart();
}
@Override
protected void onResume()
{
super.onResume();
}
@Override
protected void onPause()
{
super.onPause();
sms.save(); // autosave
}
@Override
protected void onStop()
{
super.onStop();
unbindService(connection);
// stopService(smsIntent); //doesn't appear to have any effect
}
@Override
protected void onDestroy()
{
super.onDestroy();
}
编辑:这是我的 SMServiceConnection 类的摘录,它是我的 Activity 中的私有(private)内部类,它从自定义 ServiceConnection 类扩展而来。
@Override
public void onServiceConnected(ComponentName name, IBinder service)
{
super.onServiceConnected(name, service);
msg("Service connected");
sms = getSMService();
if (sms != null)
{
String s = sms.getStuff(); //etc.; haven't listed every method invoked on sms
sms.saveSurvey();
}
} else
{
System.out.println("sms is null!");
}
}
@Override
public void onServiceDisconnected(ComponentName name)
{
super.onServiceDisconnected(name);
msg("Service disconnected");
}
我的 ServiceConnection 父类(super class)类似于:
public class MyServiceConnection implements ServiceConnection
{
private boolean serviceAvailable = false;
private SMService sms;
public void onServiceConnected(ComponentName name, IBinder service)
{
serviceAvailable = true;
LocalBinder b = (LocalBinder) service;
sms = b.getService();
}
public void onServiceDisconnected(ComponentName name)
{
serviceAvailable = false;
}
public boolean isServiceAvailable()
{
return serviceAvailable;
}
public SMService getSMService()
{
return sms;
}
}
最佳答案
您的问题可能是在您返回时再次绑定(bind)服务之前调用了 onActivityResult(),这发生在 onstart 中的 bindcall 之后。
我会尝试以下两种方法之一:
尝试将数据保存为未决信息:
if (sms == null) { mPendingResultCode = resultCode; mPedingResultData = new Bundle(intent.getExtras()); } else { handleData(resultCode, intent.getExtras()); }
然后在
onServiceConnected
调用handleData(mPedingResultCode, mPedingResultData)
如果例如mPendingResultData != null
并确保取消设置 mPendingResultCode 和 mPendingResultData 或者 完成数据后的一些其他指标。
我不确定这一点,但也许会尝试通过在 onActivityResult 中执行以下操作将数据处理添加到事件队列的后面:
final Bundle data = new Bundle(intent.getExtras); new Handler().postRunnable(new Runnable() { public void run() { "do some stuff with data and resultcode (which should be final in the parameter list anyway)" } }
正如您所说,您不应该更改 list 以在方向更改时不重新创建。这是一个丑陋的 hack,不能解决问题,我不喜欢这样的建议。如果您这样做,如果某些其他配置(例如语言)发生更改,或者如果 Activity 已被框架暂时销毁以节省资源,您仍然有可能发生同样的事情。
list 中的 configchanges 必须仅在您想要获得更改的回调而不是重新创建时使用。原因。懒惰不是其中之一。
关于android - 屏幕方向更改后返回 Activity 时丢失对 Android 服务的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9332187/