好的,这让我疯了。我有一个工作线程,(网络调用)需要单独运行UI线程,(它实际上是一个ThreadPoolExecutor但我简化它来证明我的观点)。如果以纵向方式运行此代码,而不进行旋转,则文本将更新。我把延迟放在那里以允许轮换显示我的问题。如果以纵向开始,在文本更新旋转到横向之前,文本不会更新。如果您对代码进行注释,则可以看到侦听器触发,但文本永远不会更新。
我正在尝试模拟在单独的线程中运行的自定义网络调用,如果用户在其间旋转然后数据丢失,则可能需要一些时间才能返回。我们正在尝试阻止多个网络呼叫以节省手机上的数据使用情况。
package com.example.test;
import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.content.res.Configuration;
import android.view.Menu;
import android.widget.TextView;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int orientation = getResources().getConfiguration().orientation;
if (Configuration.ORIENTATION_LANDSCAPE == orientation) {
//Do SomeThing; // Landscape
} else {
startBackgroundWork();
//Do SomeThing; // Portrait
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private Handler mHandler = new Handler();
public void startBackgroundWork() {
new WorkingThread(new SomeListener() {
public void onSomethingDone(final Object result) {
mHandler.post(new Runnable() {
public void run() {
((TextView)findViewById(R.id.text)).setText((String)result);
//showMyDialog(result);
}
});
}
}).start();
}
public interface SomeListener {
public void onSomethingDone(Object result);
}
public class WorkingThread extends Thread {
private SomeListener mListener;
public WorkingThread(SomeListener listener) {
mListener = listener;
}
public void run() {
/* do some work */
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mListener.onSomethingDone("New Text");
}
}
}
答案 0 :(得分:1)
这是因为在轮换时,会重新创建活动,因此您的所有代码都绑定到旧活动。你应该引用你的工作线程:
private static WorkingThread mWorkingThread;
public void startBackgroundWork() {
mWorkingThread = new WorkingThread(new SomeListener() {
public void onSomethingDone(final Object result) {
mHandler.post(new Runnable() {
public void run() {
((TextView)findViewById(R.id.text)).setText((String)result);
//showMyDialog(result);
}
});
}
}).start();
}
然后onCreate更新它:
public class WorkingThread extends Thread {
private SomeListener mListener;
public WorkingThread(SomeListener listener) {
mListener = listener;
}
public void run() {
/* do some work */
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mListener.onSomethingDone("New Text");
}
public void updateListener(SomeListener listener) {
mListener = listener;
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startBackgroundWork();
}
public void startBackgroundWork() {
if (mWorkingThread == null || mWorkingThread.isFinished()) { // Use a boolean to know if it still running
mWorkingThread = new WorkingThread(new SomeListener() {
public void onSomethingDone(final Object result) {
mHandler.post(new Runnable() {
public void run() {
((TextView)findViewById(R.id.text)).setText((String)result);
//showMyDialog(result);
}
});
}
});
mWorkingThread.start();
} else {
mWorkingThread.updateListener(new SomeListener() {
public void onSomethingDone(final Object result) {
mHandler.post(new Runnable() {
public void run() {
((TextView)findViewById(R.id.text)).setText((String)result);
//showMyDialog(result);
}
});
}
});
}
}
但是你可以做一些改进:
WorkingThread类应该是静态的,以避免直接引用旧活动:Java: Static vs non static inner class
然后引用当前活动,并在重新创建时更新
制作更新文本的方法,而不是将代码直接放在侦听器中