0

我有一个活动(主要活动),它显示在另一个线程上运行的操作的进度。它有一个被线程调用的处理程序成员,这个处理程序更新进度条等。

如果在此过程中改变了方向,则活动将被销毁并在另一个方向上重新创建。有什么建议可以解决这个问题吗?这一定是一个足够普遍的问题,但我认为我不理解范式。我对android开发很陌生,这似乎是一个基础问题。希望这里有人可以提供帮助。

例子。SomeClass 获取对处理程序的引用(方法 SomeClass.setHandler()),并向其发送带有状态信息的消息。

public class MainActivity extends Activity {

private Handler handler;

private createHandler() 
{
   handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
          // updates views in MainActivity, e.g. ProgressBar and TextView
        }
   }
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    createHandler();
}

protected void doThingsInSepThread() {
    Thread t = new Thread(new Runnable () {
       @Override
       public void run() {
          SomeClass sc = new SomeClass();
          sc.setHandler(handler);
          sc.method();
       }
    });
}

....

};

4

1 回答 1

4

这是一个非常常见的问题,因为如果您更改方向,Activity 将被销毁并重新创建。因此,您的处理程序丢失了,因为您认识到。您不能在 onSaveInstanceState() 中保存 Handler,因为它只接受具有 Parcelable/Serializable 接口的对象,而 Handler 没有这些。

一种可能性是(是)在这种情况下不推荐使用保存对象实例的方法

@Override
public Object onRetainNonConfigurationInstance() {
    if(handler != null)
        return handler;
    else 
        return null;
}

在您的 onCreate 中,您可以使用

Handler savedHandler = (Handler) getLastNonConfigurationInstance();
if(savedHandler != null)
    handler = savedHandler;

但是因为它已被弃用,你应该使用另一个选项来处理这个问题。

如果你想坚持你的线程,你应该考虑一个Non-UI Fragment and set retainInstanceState(true). 有了这个,Fragment 可以在 Activity 的重新创建中幸存下来,并且您的 Thread 被保存。这是一个很好的教程,但它使用了 AsyncTask。只需用您的线程替换它就可以了。

另一种可能性是 IntentService。看看这个教程l。

这是 IMO 在 Android 中进行线程处理的最佳两个选项。

于 2013-09-17T23:53:28.213 回答