【问题标题】:Android's Activity.runOnUiThread is not static, so how can i use it?Android 的 Activity.runOnUiThread 不是静态的,那么我该如何使用它呢?
【发布时间】:2011-09-24 14:01:20
【问题描述】:

例如,如果我有一个线程在做昂贵的事情,并且我想从那个线程中触发 Main(活动)类中的 runOnUiThread。显然我不应该创建我的活动类(主)的实例。所以如果我尝试

 Main.runOnUiThread(mRunnable);

在我的线程中,它给了我一个错误,说它不是静态方法,因此无法以我的方式访问它。现在我的理解是,几乎以静态方式访问活动类。
我该怎么做?

(顺便说一句:我这样做是因为我得到了CalledFromWrongThreadException,只有创建视图层次结构的原始线程才能触及它的视图

【问题讨论】:

  • 你可以使用Main.this.runOnUiThread(mRunnable);表达式。

标签: android multithreading user-interface android-activity static


【解决方案1】:

Raunak 的想法是正确的。我将补充一点,您还可以在方法 sendEmptyMessage 中指定一个整数作为处理程序的标识符。这将允许您创建一个可以处理所有 UI 更新的处理程序,例如

public static final int EXAMPLE = 0;
public static final int ANOTHER_EXAMPLE = 1;

private final Handler handler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
        switch( msg.what ){
            case EXAMPLE: 
                //Perform action
                break;
            case ANOTHER_EXAMPLE;
                //Perform action
                break;
        }
    }
} 

//Call to submit handler requesting the first action be called
handler.sendEmptyMessage(EXAMPLE);

希望这会有所帮助!

【讨论】:

【解决方案2】:

您应该使用Handler 类。处理程序类在 UI 线程上运行。当你在你的线程中完成工作时,调用handler.sendEmptyMessage(),你可以从那里对你的用户界面进行更改。

private final Handler handler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
         // make changes to ui
    }
} 

【讨论】:

  • 这个答案具有误导性。来自Handler 的文档:当您创建一个新的处理程序时,它会绑定到正在创建它的线程的线程/消息队列——从那时起,它将向该消息传递消息和可运行文件队列并在它们从消息队列中出来时执行它们。 换句话说,只有在 UI 线程上创建对象时,它才会在 UI 线程上运行。
  • 请参阅stackoverflow.com/a/25250494/199364 了解如何解决此问题,使其始终在 UI 线程上。
【解决方案3】:

您的问题并没有真正提供足够的细节,但从事情的声音来看,您在您的活动(Main)中处于私有内部类(Runnable?)中。如果是这样,你可以写:

Main.this.runOnUiThread(mRunnable);

runOnUiThread(mRunnable); //will see that there is no runOnUiThread in the current class and begin looking "upwards"

此外,您可能需要查看AsyncTask,特别是在 UI 线程上运行的 onPostExecuteonPreExecuteonProgressUpdate 回调。

【讨论】:

  • AsyncTask 只能有 6 个实例
  • @IgorGanapolsky 你什么意思?
  • 最多可以同时生成 6 个。因此,例如,如果您有一个包含数十个位图要加载的 ListView,它将无法正常工作。
  • Android 2.2 中线程限制发生了变化,见this answer
【解决方案4】:

首先在onCreate 之外创建一个runnable。像这样:

private Runnable myRunnable = new Runnable() {
        @Override
        public void run() {

                        //work to be done

        }
    };

然后调用runnable使用:

runOnUiThread(myRunnable);

【讨论】:

  • 这个只能在YourActivity里面运行
  • 嗨@IgorGanapolsky 答案已被编辑...请查看您的评论...谢谢:)
  • 答案已更新,现在即使在活动之外也可以使用 :)
【解决方案5】:

以上所有答案都不是很正确。

1)如果您希望一段代码在任何线程代码库的 UI 线程上运行。你可以做: Looper.getMainLooper().post(new Runnable(...))

因为 Looper.getMainLooper() 是一个静态变量,并且在 ActivityThread 中初始化。

2) 如果您的可运行代码 sn-p 在活动中 那么你可以使用:

MainActivity.this.runOnUiThread(...)

【讨论】:

    【解决方案6】:

    对于那些正在寻找简单的即时解决方案的人,请遵循简单的步骤

    • 在您的 onCreate() 方法之前引用您的课程

      MyClass obj;
      
    • 在你的onCreate()方法中初始化它

      obj = MyClass.this;
      
    • 致电runOnUiThread()

      obj.runOnUiThread(new Runnable() {
          public void run() {
          //perform your UI tasks here
          }
      });
      

    希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 2019-12-25
      • 1970-01-01
      • 2010-10-13
      • 2010-10-07
      • 2011-04-26
      • 2010-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多