我有一个线程需要一直从网络接收数据,我希望这些数据显示给EditText对象。
显然,我无法从接收线程中访问UI EditText;我读到的是我可以使用AsyncTask但是阅读Painless Threading中的示例在我看来,我必须完成接收数据才能将结果发布到UI组件。
我不能使用post或postDelayed,因为两者都将在UI线程上运行,我无法阻止UI接收数据;我需要不断收到数据。
我还有其他选择吗?
答案 0 :(得分:1)
使用LocalBroadcastManager,包含TextView的Activity将开始侦听广播:
public class MyActivity extends Activity {
private TextView mTextView;
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getStringExtra("actionType");
if(action.equals("updateTextView")){
mTextView.setText("whatever you want to set");
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Start listening, you can put it on onResume too
LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver, new IntentFilter(MyActivity.class.getSimpleName()));
mTextView = (TextView) findViewById(R.id.something);
}
}
因此,每当您的线程收到需要更新屏幕的内容时,请调用:
Intent intent = new Intent(MyActivity.class.getSimpleName());
intent.putExtra("actionType", "updateTextView");
// Once this is called, your broadcast receiver in MyActivity should receive it and start processing
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
还要记得在onDestroy或onPause中取消注册。
*旁注:您需要导入android支持v4库,并且可以使用Intent.putExtra("","")通过意图传递简单的String或对象。和Inteng.getExtra("");
答案 1 :(得分:0)
另一种方法是实现数据监听器接口。
public interface DataListener{
void onUpdateData(MyData data);
}
包含需要更新的UI组件的活动将实现此接口。它将指定需要对更新的数据做什么。 您可能希望将所有实例保存在应用程序中的某个位置。 我假设您有一个不同的线程来处理网络发送/接收操作。收到数据后,您只需致电:
dataListenerInstance.onUpdateData(data)
然后它将激活您在活动中实现的处理程序。
答案 2 :(得分:0)
在MainActivity中调用AsyncTask,但是使用@Override方法onPostExecute(..)
public class MainActivity extends ActionBarActivity{
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(Utils.isNetworkAvailable(this)) {
DownloadFileFromURL downloader = new DownloadFileFromURL(){
@Override
protected void onPostExecute(Integer file_content) {
onCompleteLoad();
}
};
downloader.execute(new String[]{file_url, fileName});
...
onCompleteLoad(); - 将在MainActivity的UI线程中调用。你甚至不需要实现接口!
Secon方式更适合服务器解决方案,但也可以在客户端上使用它是Callable
public class DoGetSize implements Callable<Integer> {
private final String file_url;
private int lenghtOfFile = -1;
public DoGetSize(String file_url) {
this.file_url = file_url;
}
public Integer call() {
try {
URL url = new URL(file_url);
URLConnection connection = url.openConnection();
connection.connect();
lenghtOfFile = connection.getContentLength();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return lenghtOfFile;
}
}
并称之为:
FutureTask<Integer> task = new FutureTask(new DoGetSize(file_url));
ExecutorService es = Executors.newSingleThreadExecutor();
es.submit (task);
try {
Integer result = task.get();
File file = new File(fileName);
if(file.length() != result.intValue()) {
// Do something
...
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
您可以通过这种方式发送和接收任何对象
完整示例请参阅github:https://github.com/app-z/OffLineShop/blob/master/app/src/main/java/net/appz/offlineshop/offlineshop/MainActivity.java
答案 3 :(得分:-1)
您可以使用简单的委派来完成此操作。
class NonUIThread {
private NonUIThreadDelegate delegate; //NonUIThreadDelegate can be an interface or an object that has access to your UI thread like an Activity
public void setDelegate(NonUIThreadDelegate delegate) {
this.delegate = delegate;
}
private void doSomthing() {
//do something and at the end:
delegate.someMethodThatUpdatesThatComponent();
}
}
class TheUIThread implements NonUIThreadDelegate /*assuming you've decided to make NonUIThreadDelegate an interface*/ { // the "delegator"
/*
your code
*/
private void initiateNonUIThread() {
NonUIThread nonUIThread;
/*do whatever needed*/
nonUIThread.setDelegate(this);
nonUIThread.start();
}
public void someMethodThatUpdatesThatComponent() { //will be called by the non ui thread
//update the UI
}
}
这里解释得更好(当然使用AsincTask):Simple Delegation Pattern in Android