post方法到底是做什么的?

我遇到了一个非常奇怪的function。

当我试图在主线程上运行animation时,它不会启动。 当我运行所说的animation使用

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

它开始。

在开始animation之前我已经打印了CurrentThread并且都打印了main

显然,我在这里错过了一些东西,因为两者都应该在主线程上启动animation…我的猜测是,当post将任务添加到队列中时,它会从更“正确的时间”开始,但我很想知道这里发生更深层次的事情。

编辑:让我清除一些东西 – 我的问题是,为什么开始后animation导致它开始,当在主线程上启动animation没有。

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

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

run() :开始执行类的代码的活动部分。 当一个线程被启动时,这个方法被调用,这个线程是用一个实现了Runnable的类创build的。

 getView().**post**(new **Runnable**() { @Override public void run() { getView().startAnimation(a); } }); 

代码getView().startAnimation(a);

在你的代码中,

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

所以当startAnimation从messageQueue中获取时,会在新线程中触发

[编辑1]

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

UI主题:

  • 当应用程序启动时,Ui线程自动创build

  • 它负责将事件发送到适当的小部件,这包括绘图事件。

  • 这也是您与Android小部件交互的线程

例如,如果您触摸屏幕上的一个button,则UI线程将触发事件分派给小部件,该小部件依次设置其按下的状态并向事件队列发布无效请求。 UI线程使请求出队,并通知小部件重绘本身。

如果用户按下一个可以长时间运行的button,会发生什么?

 ((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(可运行)
  • View.postDelayed(Runnable,long)
  • 处理器

如下所示,

View.post(可运行)

 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(); (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/

这是在onCreate或onCreateView? 如果是这样,应用程序可能不处于视图附加到窗口的状态。 许多基于视图度量的algorithm可能无法工作,因为视图的度量和位置等事情可能还没有被计算出来。 Androidanimation通常要求他们运行UImath

View.post实际上将视图的消息循环中的animation排队,所以一旦视图被附加到窗口上,它就会执行animation,而不是手动执行animation。

你实际上在UI线程上运行的东西,但在不同的时间

看看这里是一个很好的答案。 view.post()与handler.post()几乎相同。 进入主线程队列并在其他未完成任务完成后执行。 如果你调用activity.runOnUiThread(),它将立即在UI线程上调用。

我认为这个问题可能是您调用post()方法的生命周期方法。 你在做onCreate()吗? 如果是这样,看看我在activity的onResume()文档中find的是什么:

的onResume()

在API级别1中添加void onResume()在onRestoreInstanceState(Bundle),onRestart()或onPause()之后调用,以便您的活动开始与用户交互。 这是开始animation ,打开专用访问设备(如相机)等的好地方

https://developer.android.com/reference/android/app/Activity.html#onResume();

所以,正如Joe Plante所说,也许视图还没有准备好在你调用post()的时候开始animation,所以试着把它移动到onResume()。

PD:实际上如果你把代码移动到onResume(),那么我认为你可以移除post()调用,因为你已经在UI线程中,并且视图应该准备好开始animation了。