首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >非UI线程修改UI组件

非UI线程修改UI组件
EN

Stack Overflow用户
提问于 2013-05-07 09:44:52
回答 4查看 137关注 0票数 0

我有一个需要一直从网络接收数据的线程,我希望将这些数据显示到EditText对象中。

显然,我不能从我的接收线程中访问UI EditText;我读到的是我可以使用AsyncTask,但在阅读Painless Threading中的示例时,我似乎必须先接收完数据,然后才能将结果发布到UI组件。

我不能使用post或postDelayed,因为它们都将在UI线程上运行,并且我不能阻塞UI来接收数据;我需要一直接收数据。

我还有其他选择吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-05-07 09:59:31

使用LocalBroadcastManager,包含TextView的活动将开始监听广播:

代码语言:javascript
复制
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);
    }
}

因此,每当你的Thread接收到需要更新屏幕的东西时,调用这个:

代码语言:javascript
复制
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("","")和Inteng.getExtra(“”)按意图传递简单的字符串或对象;

票数 1
EN

Stack Overflow用户

发布于 2013-05-07 10:06:05

另一种方法是实现数据侦听器接口。

代码语言:javascript
复制
public interface DataListener{
    void onUpdateData(MyData data);
}

包含需要更新的UI组件的活动将实现此接口。它将指定需要如何处理更新的数据。您可能希望将所有实例这些数据侦听器接口保留在应用程序中的某个位置。我假设您有一个不同的线程来处理网络发送/接收操作。在接收数据时,您只需调用:

代码语言:javascript
复制
dataListenerInstance.onUpdateData(data)

然后,它将激活您在活动中实现的处理程序。

票数 0
EN

Stack Overflow用户

发布于 2015-02-15 06:02:04

在MainActivity中调用AsyncTask,但使用@Override方法onPostExecute(..)

代码语言:javascript
复制
    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方式更适合于服务器解决方案,但也可以在客户端使用它是可调用的

代码语言:javascript
复制
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;
    }
}

然后这样叫它:

代码语言:javascript
复制
    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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16409950

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档