我正在创建一个Activity
,与Service
进行通信,通过POST
方法从互联网上下载一些数据。为此,我使用Messenger
。这是我的代码,让你更清楚:
我的onCreated()
方法:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_comments);
CommentsHandler commentsHandler = new CommentsHandler(this, savedInstanceState);
Messenger messenger = new Messenger(commentsHandler);
Intent serviceIntent = new Intent(this, WindowService.class);
serviceIntent.putExtra("messenger", messenger);
serviceIntent.putExtra("state", 888);
serviceIntent.putExtra("number", getIntent().getStringExtra("number"));
startService(serviceIntent);
}
我的Service
主题中的代码,通过Activity
对象将结果数据发布到Messenger
:
/** ... **/
Messenger messenger = intent.getParcelableExtra("messenger");
/** ... **/
Message resultMsg = this.obtainMessage();
resultMsg.obj = jParser.getArrayList(); //This is an ArrayList of my downloaded data.
messenger.send(resultMsg);
Activity
中用于处理Message
中的Service
的代码:
public static class CommentsHandler extends Handler {
Bundle mSavedInstanceState;
ActionBarActivity activity;
public CommentsHandler(Activity a, Bundle savedInstanceState) {
activity = (ActionBarActivity) a;
mSavedInstanceState = savedInstanceState;
}
@Override
public void handleMessage(Message msg) {
comments = (ArrayList<HashMap<String, String>>) msg.obj;
if (mSavedInstanceState == null && msg.arg1 != 793) {
activity.getSupportFragmentManager().beginTransaction()
.add(R.id.container, new CommentsFragment()).commit();
} else if (msg.arg1 == 793) { //793 is my preferred code to determine
//if the internet connection could not be
//established when the Service was trying
//to download the data.
activity.finish();
}
}
}
问题是:如果我打开Activity
并在下载数据之前将其关闭,则此代码.add(R.id.container, new CommentsFragment()).commit();
会向我显示错误Can not perform this action after onSaveInstanceState
,因为此代码仅在我的Service
中的数据经过Messenger
对象处理和发送,但当时Activity
已被用户关闭,因此无法添加Fragment
。如何解决这个问题?如何在添加Activity
之前检查Fragment
是否未关闭/关闭?或者,更好的是,如何在Activity
的{{1}}方法中停止运行该代码的线程,以便在onDestroy()
关闭时不会执行它?提前谢谢!
答案 0 :(得分:3)
在您的活动中,您应该创建一个布尔值来检查活动是否可见:
public ActionBarActivity extends Activity {
private boolean isActivityVisible = false;
@Override
protected void onResume(){
isActivityVisible = true;
}
@Override
protected void onPause(){
isActivityVisible = false;
}
public boolean isVisible(){
return this.isActivityVisible;
}
}
然后修改Handler类定义:
public static class CommentsHandler extends Handler {
Bundle mSavedInstanceState;
ActionBarActivity activity;
public CommentsHandler(Activity a, Bundle savedInstanceState) {
activity = (ActionBarActivity) a;
mSavedInstanceState = savedInstanceState;
}
@Override
public void handleMessage(Message msg) {
// here you check if your activity is no longer visible and then break up
if(activity == null || !activity.isVisible())
return;
comments = (ArrayList<HashMap<String, String>>) msg.obj;
if (mSavedInstanceState == null && msg.arg1 != 793) {
activity.getSupportFragmentManager().beginTransaction()
.add(R.id.container, new CommentsFragment()).commit();
} else if (msg.arg1 == 793) { //793 is my preferred code to determine
//if the internet connection could not be
//established when the Service was trying
//to download the data.
activity.finish();
}
}
}
答案 1 :(得分:1)
最小的变化是在Activity中有一个布尔字段,在onResume()
中将其设置为true,在onPause()
中设置为false,并在handleMessage()
中检查其值(即忽略)如果标志当前为false则消息。)
使用handleMessage()
执行此操作,而不是使用Messenger和BroadcastReceiver
。在onResume()
中注册接收方,并在onPause()
中取消注册。这样,服务的广播将被忽略。
无论如何,这两种解决方案基本相同,但广播有点&#34;更高级别&#34;。
如果活动暂停,则假定您对服务的结果不感兴趣。如果您(例如,如果您退出应用程序并重新登录,并且需要显示更新),那么您应该将接收的数据放在一个字段中并在以下onResume()
处理它。
答案 2 :(得分:1)
你这样做的方式与我处理它的方式不同,但是使用你拥有的东西我会做出这些调整:
public static class CommentsHandler extends Handler {
Bundle mSavedInstanceState;
ActionBarActivity activity;
public CommentsHandler(Activity a, Bundle savedInstanceState) {
activity = (ActionBarActivity) a;
mSavedInstanceState = savedInstanceState;
}
public void setActivity(Activity a){
activity = a;
}
@Override
public void handleMessage(Message msg) {
if(activity == null){
return;
}
comments = (ArrayList<HashMap<String, String>>) msg.obj;
if (mSavedInstanceState == null && msg.arg1 != 793) {
activity.getSupportFragmentManager().beginTransaction()
.add(R.id.container, new CommentsFragment()).commit();
} else if (msg.arg1 == 793) { //793 is my preferred code to determine
//if the internet connection could not be
//established when the Service was trying
//to download the data.
activity.finish();
}
}
}
然后我会使用你的活动onPause()/ onResume()方法来表示:
@Override
protected void onPause() {
super.onPause();
commentsHandler.setActivity(null);
}
@Override
protected void onResume() {
super.onResume();
commentsHandler.setActivity(this);
}