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了。