我需要从runnable更新ui。我的逻辑如下。 我从片段生命周期的onCreate开始runnable。而runnable实例负责请求网络。问题是我不知道如何在runnable实例从网络中获取数据后更新片段。
在CustomFragment.java中的片段中启动runnable的代码。
public void onCreate(Bundle savedInstanceState) {
Log.d(DEBUG_TAG, "onCreate");
super.onCreate(savedInstanceState);
accountMgr.requestAccountInfo();
}
在AccountManager.java中启动runnable的代码
/**
* request Account info from server
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void requestAccountInfo() {
Account act = getCurrentAccount();
Thread t = new Thread(new RequestAccountInfoTask(act));
t.start();
}
/**
* automatically update Account info, like space usage, total space size, from background.
*/
class RequestAccountInfoTask implements Runnable {
private Account account;
public RequestAccountInfoTask(Account account) {
this.account = account;
}
@Override
public void run() {
doRequestAccountInfo(account);
}
}
答案 0 :(得分:3)
runOnUiThread()
需要Activity
参考。还有其他选择。您不需要Activity
引用您的Thread
。您始终可以使用主循环器获取UI处理程序。传递其他参数,如您的界面,以在完成任务后更新片段。
class RequestAccountInfoTask implements Runnable {
private Account account;
private Handler mHandler;
public RequestAccountInfoTask(Account account) {
this.account = account;
mHandler = new Handler(Looper.getMainLooper());
}
@Override
public void run() {
doRequestAccountInfo(account);
//use the handler
}
}
您在实例化的Handler
上运行的任何内容都将位于UI线程上。
当然,使用runOnUiThread()
是完全合理的。
答案 1 :(得分:2)
请查看AsyncTask以从线程更新UI:
http://developer.android.com/reference/android/os/AsyncTask.html
以下是上述链接中的重点:
类概述AsyncTask可以正确,轻松地使用UI线程。 此类允许执行后台操作和发布结果 在UI线程上,无需操纵线程和/或处理程序。
AsyncTask旨在成为Thread和Handler的辅助类 并不构成通用的线程框架。 AsyncTasks 理想情况下应该用于短期操作(几秒钟的时间) 大多数。)如果你需要保持线程长时间运行, 强烈建议您使用提供的各种API java.util.concurrent包,如Executor,ThreadPoolExecutor和 FutureTask。
异步任务由在a上运行的计算定义 后台线程,其结果发布在UI线程上。一个 异步任务由3种泛型类型定义,称为Params, 进度和结果,以及4个步骤,称为onPreExecute,doInBackground, onProgressUpdate和onPostExecute。
答案 2 :(得分:2)
您可以使用runOnUIThread活动方法。
这里的代码可能会对您有所帮助:
class RequestAccountInfoTask implements Runnable {
private Account account;
public RequestAccountInfoTask(Account account) {
this.account = account;
}
@Override
public void run() {
doRequestAccountInfo(account);
if (getActivity() != null) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
// you can update fragment UI at here
}
});
}
}
}
答案 3 :(得分:1)
您无法从runnable更新UI。您需要处理程序来更新UI。有关详细信息,请参阅this。
答案 4 :(得分:0)
UI只能由创建它的线程修改。在大多数情况下是由UI线程。所以你需要使用runOnUiThread方法进行更新。祝你好运
答案 5 :(得分:0)
我知道答案有点不同。但我希望你能看到Android Annotations。哪个非常好用。我只将它们用于背景和Ui线程。通过在方法名称上编写@Background来完成后台线程中的每个任务。并在UI线程中进行所有UI更新。我建议你只检查一次。 http://androidannotations.org/ 谢谢 至于你的答案是关注。您无法从runnable更新UI。请参阅asyn任务以更新您的Ui。
答案 6 :(得分:0)
我建议使用AsynTask,或者你可以试试这个
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getActivity(), "ON UI Thread", Toast.LENGTH_LONG).show();
}
});
答案 7 :(得分:0)
您可以使用事件总线来执行此操作 - http://square.github.io/otto/ 这很简单。只需在需要更新UI时从线程发送事件:
...
//in the end of your heavy job:
bus.post(new YourEvent());
并在您的Activity创建方法中:
@Subscribe
public void onYourEvent(YourEvent event) {
//do what you want there
}
顺便说一下,你可以通过事件传递任何数据,这是你的自定义类!请阅读手册如何设置此lib,注册总线活动。它非常有用且易于使用
答案 8 :(得分:0)
您可以创建一个Runnable,然后发布到主线程。来自Google Processes and Threads
上的开发者页面此实现是线程安全的:后台操作已完成 从一个单独的线程,而ImageView总是被操纵 UI线程。
public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
// a potentially time consuming task
final Bitmap bitmap =
processBitMap("image.png");
mImageView.post(new Runnable() {
public void run() {
mImageView.setImageBitmap(bitmap);
}
});
}
}).start();
}