Android 在旋转前进行网络调用时,如何更新UI线程?
好吧,这让我快发疯了。我有一个工作线程(网络调用),需要单独运行UI线程(它实际上是一个ThreadPoolExecutor,但我简化了它以证明我的观点)。如果在纵向运行此代码而不旋转,则文本将更新。我把延迟放在那里,以允许旋转来显示我的问题。如果从纵向开始,在文本更新旋转到横向之前,文本不会更新。如果您对代码进行注释,您可以看到侦听器启动,但文本永远不会更新 我试图模拟一个在单独线程中运行的自定义网络调用,如果用户在这两个线程之间旋转,那么可能需要一些时间才能返回,然后数据就会丢失。我们正试图阻止多个网络呼叫以节省手机上的数据使用Android 在旋转前进行网络调用时,如何更新UI线程?,android,handler,threadpool,Android,Handler,Threadpool,好吧,这让我快发疯了。我有一个工作线程(网络调用),需要单独运行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");
}
}
}
这是因为在循环时,活动被重新创建,因此所有代码都绑定到旧活动。您应该参考您的工作线程:
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();
}
然后,一旦创建并更新它:
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);
}
});
}
});
}
}
但是你可以做一些改进:
- WorkingRead类应该是静态的,以避免直接引用旧活动:
- 然后引用当前活动,并在重新创建时更新它
- 创建一个更新文本的方法,而不是将代码直接放在侦听器中
- 这是因为在轮换时,活动被重新创建,因此您的所有代码都绑定到旧活动。您应该参考您的工作线程:
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();
}
然后,一旦创建并更新它:
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);
}
});
}
});
}
}
但是你可以做一些改进:
- WorkingRead类应该是静态的,以避免直接引用旧活动:
- 然后引用当前活动,并在重新创建时更新它
- 创建一个更新文本的方法,而不是将代码直接放在侦听器中