android - post方法到底是做什么的?

我遇到了一个很奇怪的功能。

当我尝试在主线程上运行动画时,它没有启动。 当我使用

运行所述动画时
getView().post(new Runnable() {
            @Override
            public void run() {
                getView().startAnimation(a);
            }
        });

它确实开始了。

我在开始动画之前打印了 CurrentThread 并且都打印了 main

显然,我在这里遗漏了一些东西,因为两者都应该在主线程上启动动画...... 我的猜测是,随着 post 将任务添加到队列中,它会在更“正确的时间”开始,但我很想更深入地了解这里会发生什么。

编辑: 让我澄清一下 - 我的问题是,为什么在 post 上启动动画会导致它启动,而在主线程上启动动画却不会。

最佳答案

post :post 导致 Runnable 被添加到消息队列中,

Runnable : 表示可以执行的命令。通常用于在不同的线程中运行代码。

run () :开始执行类代码的 Activity 部分。当一个线程启动时调用此方法,该线程已使用实现 Runnable 的类创建。

getView().post(new Runnable() {

         @Override
         public void run() {
             getView().startAnimation(a);
         }
     });

代码 : getView().startAnimation(a);

在你的代码中,

post 使 Runnable(代码 将在不同的线程中运行)添加消息队列。

所以当从 messageQueue

中获取 startAnimation 时,它将在一个新线程中被触发

[编辑 1]

为什么我们使用新线程而不是 UI 线程(主线程)?

用户界面线程:

  • 应用程序启动时,会自动创建 Ui Thread

  • 它负责将事件分派(dispatch)给适当的小部件 这包括绘图事件。

  • 它也是你与 Android 小部件交互的线程

For instance, if you touch the a button on screen, the UI thread dispatches the touch event to the widget which in turn sets its pressed state and posts an invalidate request to the event queue. The UI thread dequeues the request and notifies the widget to redraw itself.

如果用户按下一个会执行 longOperation 的按钮会发生什么?

((Button)findViewById(R.id.Button1)).setOnClickListener(           
             new OnClickListener() {        
        @Override
    public void onClick(View v) {
            final Bitmap b = loadImageFromNetwork();
            mImageView.setImageBitmap(b);
}
});

用户界面卡住。程序甚至可能崩溃。

public void onClick(View v) {
  new Thread(new Runnable() {
    public void run() {
        final Bitmap b = loadImageFromNetwork();
        mImageView.setImageBitmap(b);
    }
  }).start();
}

它打破了从不直接从工作线程更新 UI

的 android 规则

Android 提供了几种从其他线程访问 UI 线程的方法。

  • Activity.runOnUiThread(可运行)
  • View.post(Runnable)
  • View.postDelayed(Runnable, long)
  • 处理程序

如下所示,

View.post(Runnable)

public void onClick(View v) {
  new Thread(new Runnable() {
    public void run() {
      final Bitmap b = loadImageFromNetwork();
      mImageView.post(new Runnable() {
        public void run() {
          mImageView.setImageBitmap(b);
        }
      });
    }
  }).start();
}

处理程序

final Handler myHandler = new Handler(Looper.getMainLooper());

(new Thread(new Runnable() {

    @Override
    public void run() {
       final Bitmap b = loadImageFromNetwork();
      myHandler.post(new Runnable() {                           

        @Override
        public void run() {
           mImageView.setImageBitmap(b);
          }
        });
      }
    })).start();                
}

更多信息

http://android-developers.blogspot.com/2009/05/painless-threading.html

http://www.aviyehuda.com/blog/2010/12/20/android-multithreading-in-a-ui-environment/

https://stackoverflow.com/questions/13840007/

相关文章:

android - 移动和消失的代码行; Eclipse 的 XML 编辑器的问题

android - 如何在 Android 中更改代理设置(尤其是在 Chrome 中)

android - 如何查看 Google Play 服务版本?

Android 5.1.1 及更高版本 - getRunningAppProcesses() 仅返回

android - 以编程方式获取设备的 Android API 级别?

android - 在 Android 中通过 Canvas 创建一个空位图并进行绘图

android - 将 largeHeap 设置为 true 有什么好处?

android - 了解 keystore 、证书和别名

android - 如何在 Android 中模拟触摸事件?

android - 在非 Activity 类中获取上下文