面白い問題が発生しました。ビューが遅れずに更新されたときに「ビュー階層を作成した元のスレッドのみがビューにアクセスできます」
final Button myButton = (Button)findViewById(R.id.myButton);
final TextView myTextView = (TextView)findViewById(R.id.myTextView);
final Thread thread = new Thread(new Runnable() {
@Override
public void run() {
myTextView.setText("Hello text");
}
});
myButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
thread.start();
}
});
か:あなたは活動のonCreate/onStart/onResume
方法に次のコードを記述する場合
final TextView myTextView = (TextView)findViewById(R.id.myTextView);
final Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.currentThread().sleep(500);
}
catch (InterruptedException e) {
e.printStackTrace();
}
myTextView.setText("Hello text");
}
});
thread.start();
は、エラーがスローされ、それはすべきか
android.view.ViewRoot $ CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views."
それはあることは明らかですこの場合は、ui-threadでビューを更新する必要があります(Handler, AsyncTask, runOnUiThread, view.post).
しかし、別のスレッドのビューを遅く(スリープ呼び出しをせずに、またはボタンを押してスレッドを開始せずに)更新すると、例外はスローされません。
final TextView myTextView = (TextView)findViewById(R.id.myTextView);
final Thread thread = new Thread(new Runnable() {
@Override
public void run() {
myTextView.setText("Hello text");
}
});
thread.start();
なぜこのような動作があるのですか?
UPDATE:
私は、Androidのソースコードを学んだし、次の結論に達したてきました。 ナンディーは真実を書きました。 ビューの初期化時に、mAttachInfoフィールドを初期化するViewのdispatchAttachedToWindow(AttachInfo info、int visibility)メソッドが呼び出されました。 mAttachInfoオブジェクトにはmViewRootImplフィールドがあります。それがnullの場合、getViewRootImplはnullを返します:
public ViewRootImpl getViewRootImpl() {
if (mAttachInfo != null) {
return mAttachInfo.mViewRootImpl;
}
return null;
}
ViewRootImplはcheckThreadメソッドが含まれています。これはスレッドを比較します。ビューを作成したスレッドと、ビューの更新要求のスレッドです。
void checkThread() {
if (mThread != Thread.currentThread()) {
throw new CalledFromWrongThreadException(
"Only the original thread that created a view hierarchy can touch its views.");
}
}
したがって、ビューが初期化されていない場合、チェックと変更は例外をスローしません。
はい、遅延パラメータも試しました。しかし、なぜ私は不思議に思っています。 スレッドが初期化するまでに時間がかかり、その間にui-componentが変更されるようです。しかし、私はドキュメンテーションでこれについては言及していません。 –
「遅延」は、「nandeesh」が答えていることによると思います。それはおそらく答えです。 – Luksprog