gpt4 book ai didi

android - 在旋转之前放置网络调用时如何更新 UI 线程?

转载 作者:行者123 更新时间:2023-11-30 03:26:30 25 4
gpt4 key购买 nike

好吧,这让我抓狂。我有一个工作线程(网络调用)需要独立于 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");
}
}
}

最佳答案

这是因为在轮换时, Activity 被重新创建,因此您的所有代码都绑定(bind)到旧 Activity 。您应该引用您的工作线程:

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 类应该是静态的,以避免直接引用旧 Activity :Java: Static vs non static inner class

  • 然后引用当前 Activity ,并在重新创建时更新它

  • 创建一个更新文本的方法,而不是直接在监听器中编写代码

关于android - 在旋转之前放置网络调用时如何更新 UI 线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18140537/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com