我遇到了一个非常奇怪的功能.
当我试图在主线程上运行动画时,它不会启动.当我使用运行所述动画
getView().post(new Runnable() {
@Override
public void run() {
getView().startAnimation(a);
}
});
Run Code Online (Sandbox Code Playgroud)
它确实开始了.
我CurrentThread
在开始动画之前打印过并打印出来main
.
显然,我在这里遗漏了一些东西,因为两者都应该在主线程上启动动画......我的猜测是,当post将任务添加到队列中时,它会在更"正确的时间"开始,但我很想知道这里发生的事情更深入.
编辑:让我清楚一点 - 我的问题是,为什么在帖子上启动动画会导致它启动,当在主线程上启动动画时没有.
Tal*_*lha 150
post:post导致Runnable被添加到消息队列中
Runnable:表示可以执行的命令.通常用于在不同的Thread中运行代码.
run() :开始执行类'代码的活动部分.当启动一个使用实现Runnable的类创建的线程时,将调用此方法.
getView().post(new Runnable() {
@Override
public void run() {
getView().startAnimation(a);
}
});
Run Code Online (Sandbox Code Playgroud)
代码:getView().startAnimation(a);
在你的代码中,
post导致Runnable(代码将在不同的线程中运行)添加消息队列.
因此,当从messageQueue获取startAnimation时,将在新线程中触发startAnimation
[编辑1]
为什么我们使用新线程而不是UI线程(主线程)?
UI线程:
启动应用程序时,将自动创建Ui线程
它负责将事件分派给适当的小部件,这包括绘图事件.
它也是您与Android小部件交互的线程
例如,如果触摸屏幕上的a按钮,UI线程会将触摸事件调度到窗口小部件,窗口小部件又设置其按下状态并将无效请求发布到事件队列.UI线程将请求出列并通知窗口小部件重绘自身.
如果用户按下将执行longOperation的按钮会发生什么?
((Button)findViewById(R.id.Button1)).setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View v) {
final Bitmap b = loadImageFromNetwork();
mImageView.setImageBitmap(b);
}
});
Run Code Online (Sandbox Code Playgroud)
用户界面冻结了.该计划甚至可能会崩溃.
public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
final Bitmap b = loadImageFromNetwork();
mImageView.setImageBitmap(b);
}
}).start();
}
Run Code Online (Sandbox Code Playgroud)
它打破了永远不会直接从工作线程更新UI的android规则
Android提供了几种从其他线程访问UI线程的方法.
如下,
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();
}
Run Code Online (Sandbox Code Playgroud)
处理器
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();
}
Run Code Online (Sandbox Code Playgroud)
有关更多信息
http://android-developers.blogspot.com/2009/05/painless-threading.html
http://www.aviyehuda.com/blog/2010/12/20/android-multithreading-in-a-ui-environment/
Joe*_*nte 24
这是在onCreate还是onCreateView上完成的?如果是这样,应用程序可能不处于视图附加到窗口的状态.许多基于View指标的算法可能无效,因为可能尚未计算View的测量值和位置等.Android动画通常要求它们通过UI数学运行
View.post实际上是在View的消息循环中对动画进行排队,因此一旦视图附加到窗口,它就会执行动画而不是手动执行.
您实际上是在UI线程上运行,但是在不同的时间运行
我认为问题可能是您调用 post() 方法的生命周期方法。你是在onCreate()中做的吗?如果是这样,请查看我在活动的 onResume() 文档中找到的内容:
onResume()
在 API 级别 1 中添加 void onResume () 在 onRestoreInstanceState(Bundle)、onRestart() 或 onPause() 之后调用,以便您的 Activity 开始与用户交互。这是开始动画、打开独占访问设备(例如相机)等的好地方。
https://developer.android.com/reference/android/app/Activity.html#onResume()
因此,正如 Joe Plante 所说,也许在调用 post() 时视图还没有准备好启动动画,因此请尝试将其移至 onResume()。
PD:实际上,如果您确实将代码移至 onResume() 那么我认为您可以删除 post() 调用,因为您已经在 ui 线程中并且视图应该准备好启动动画。