先看下总结在考虑要不要继续
总结:^_^
view.post()方法不一定要在主线程中去调用
在onCreate()方法中去调用可以获取view的宽高,前提是主线程
在子线程中调用view.post()方法可以起作用,但要注意调用的时机,在onAttachedToWindow后去调用
在子线程中正确的调用view.post()方法run方法回到主线程,view.post()方法主要是为了异步通讯
可以在onAttachedToWindow方法中修改窗口的大小
遇到这个问题一定是在onCreate()方法中创建了子线程去调用的这个方法。
大多数用到这个方法是为了获取view的宽高,如果直接在主线程中是可以获取的,如果偏要创建子线程去调用,那么打死也不会执行的,因为你写错地方了。
public class EditTextActivity extends AppCompatActivity {
private TextEditView editText;
private PDFView pdfView;
private boolean isEdit;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_text);
editText = findViewById(R.id.tv_edit);
editText.post(new Runnable() {
@Override
public void run() {
Log.e("------------->","1、主线程"+Thread.currentThread().getName());
}
});
new Thread(new Runnable() {
@Override
public void run() {
Log.e("------------->","2、子线程线程"+Thread.currentThread().getName());
editText.post(new Runnable() {
@Override
public void run() {
Log.e("------------->","3、子线程的run方法"+Thread.currentThread().getName());
}
});
}
}).start();
}
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
Log.e("------------->","4、onAttachedToWindow"+Thread.currentThread().getName());
new Thread(new Runnable() {
@Override
public void run() {
Log.e("------------->","5、onAttachedToWindow子线程"+Thread.currentThread().getName());
editText.post(new Runnable() {
@Override
public void run() {
Log.e("------------->","6、onAttachedToWindow子线程run方法"+Thread.currentThread().getName());
}
});
}
}).start();
}
@Override
protected void onResume() {
super.onResume();
Log.e("------------->","7、onResume"+Thread.currentThread().getName());
}
运行的效果
08-28 14:18:26.886 14635-14635/com.example.a_0102.mylearn E/------------->: 7、onResumemain
08-28 14:18:26.896 14635-15149/com.example.a_0102.mylearn E/------------->: 2、子线程线程Thread-11192
08-28 14:18:26.906 14635-14635/com.example.a_0102.mylearn E/------------->: 4、onAttachedToWindowmain
08-28 14:18:26.906 14635-15151/com.example.a_0102.mylearn E/------------->: 5、onAttachedToWindow子线程Thread-11193
08-28 14:18:26.956 14635-14635/com.example.a_0102.mylearn E/------------->: 1、主线程main
08-28 14:18:26.956 14635-14635/com.example.a_0102.mylearn E/------------->: 6、onAttachedToWindow子线程run方法main
看到了吧3没有执行,而在onAttachedToWindow中的却执行了。
只能去看源码了:
/**
* <p>Causes the Runnable to be added to the message queue.
* The runnable will be run on the user interface thread.</p>
*
* @param action The Runnable that will be executed.
*
* @return Returns true if the Runnable was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting.
*
* @see #postDelayed
* @see #removeCallbacks
*/
public boolean post(Runnable action) {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
return attachInfo.mHandler.post(action);
}
// Postpone the runnable until we know on which thread it needs to run.
// Assume that the runnable will be successfully placed after attach.
getRunQueue().post(action);
return true;
}
一进去就懵圈了,mAttachInfo这个东东什么时候给赋值的,找起来:
/**
* @param info the {@link android.view.View.AttachInfo} to associated with
* this view
*/
void dispatchAttachedToWindow(AttachInfo info, int visibility) {
mAttachInfo = info;
……
performCollectViewAttributes(mAttachInfo, visibility);
onAttachedToWindow();
……
}
看到了吧,我们又不能重写dispatchAttachedToWindow()方法但是我们看到了onAttachedToWindow()方法,那就从他动手吧哈哈。
这个post就相当于把这个Runnable添加到了主线程的那个队列中,然后等待执行
具体的分析流程参考
view.post原理,和handler.post的区别
关于onAttachedToWindow什么时候执行,就参考这篇文章吧,通过打log和看文档就可以知道
onAttachedToWindow()在整个Activity生命周期的位置及使用