[英]How to update UI thread when Network call is placed before rotating?
好吧,这真让我发疯。 我有一个工作线程(网络调用),它需要与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();
}
然后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:静态与非静态内部类
然后引用当前活动,并在重新创建活动时对其进行更新
创建一种更新文本的方法,而不是将代码直接放在侦听器中
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.