在非 UI 线程中做一些 Android UI 的事情

Posted

技术标签:

【中文标题】在非 UI 线程中做一些 Android UI 的事情【英文标题】:Do some Android UI stuff in non-UI thread 【发布时间】:2011-09-07 13:54:52 【问题描述】:

有没有办法在非 UI 线程中进行 UI 更改?简短的问题。

【问题讨论】:

【参考方案1】:

使用Handler 或使用以下代码

    runOnUiThread(new Runnable()
               
        @Override
        public void run()
        
            // Ui Stuff here                
        
    );

【讨论】:

【参考方案2】:

有很多方法可以做到这一点,使用AsyncTask or Threads。简短的回答。

提示:UI 的东西可以在 pre-postExecute/runOnUiThread/Handler 类中完成

【讨论】:

【参考方案3】:

如果您不想使用 AsyncTask,请在您的主要活动中尝试使用内部类 (ResponseHandler) 的观察者模式,抱歉我无法正确设置格式,但我确定您明白了

public class WorkerThread extends Observable implements Runnable 
public void run() 
    try 
            DoSomething();
            String response = "Doing something";
            setChanged();
            notifyObservers( response );
            DoSomethingElse();
            String response = "Doing something else";
            setChanged();
            notifyObservers( response );
    
    catch (IOException e) 
        e.printStackTrace();
    

private void DoSomething()

private void DoSomethingElse()



public class MainActivity
public class ResponseHandler implements Observer 
    private String resp;
    public void update (Observable obj, Object arg) 
        if (arg instanceof String) 
            resp = (String) arg;
            //Write message to UI here ie System.out.println("\nReceived Response: "+ resp );
            //or EditText et = (EditText)findViewById(R.id.blah);
            // blah.SetText(resp);
        
    

private void doStuffAndReportToUI()
    final WorkerThread wt = new WorkerThread();
    final ResponseHandler respHandler = new ResponseHandler();
    wt.addObserver( respHandler );
    Thread thread = new Thread(wt);
    thread.start();

【讨论】:

【参考方案4】:

查看Handler 课程。或者看看这些类似的问题:

Update UI from Thread

Handling UI code from a Thread

updating the ui from thread using audiotrack

【讨论】:

嗯,基本问题是,该线程在我的主要活动之外的其他类中,并且它在无限循环中做某事(套接字等)。【参考方案5】:

尝试探索runOnUIThread()

http://developer.android.com/reference/android/app/Activity.html#runOnUiThread(java.lang.Runnable)

【讨论】:

【参考方案6】:

我试过 +tmho 答案,但它仍然给出这个错误:

E/AndroidRuntime(****): android.view.ViewRootImpl$CalledFromWrongThreadException: 只有创建视图层次结构的原始线程才能接触其视图。

我最终将它与 +ingsaurabh 方式结合起来,就像这样:

private class ResponseHandler implements Observer, Runnable 

    Activity act;

    public ResponseHandler(Activity caller) 
        act = caller;
    

    @Override
    public void update (Observable obj, Object arg) 
        act.runOnUiThread(this);
    

    @Override
    public void run() 
        //update UI here
    

谢谢你们。

【讨论】:

以上是关于在非 UI 线程中做一些 Android UI 的事情的主要内容,如果未能解决你的问题,请参考以下文章

为何invalidate()不可以直接在UI线程中调用

UWP 在非UI线程中更新UI

为啥loop之后就可以子线程更新ui

android Socket编程注意点

在非 UI 线程上运行 async/await 方法[关闭]

WinForm中在非UI线程更改控件值的办法