java android - 引起:android.view.ViewRootImpl$CalledFromWrongThreadException
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11204079/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
android - Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException
提问by chinna_82
Possible Duplicate:
Android - ViewRootImpl$CalledFromWrongThreadException
Im trying to get image from my URL and display in application but it throw error Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. Below is my code
我试图从我的 URL 获取图像并在应用程序中显示,但它引发错误:android.view.ViewRootImpl$CalledFromWrongThreadException:只有创建视图层次结构的原始线程可以触摸其视图。下面是我的代码
Code
代码
package com.smartag.bird.dev;
public class MainActivity extends Activity {
static String ndefMsg = null;
static String ndefMsg1 = null;
NfcAdapter mNfcAdapter;
PendingIntent mNfcPendingIntent;
IntentFilter[] mNdefExchangeFilters;
static final String TAG = "Read Tag";
TextView mTitle;
private static ImageView imageView;
static String url = "http://sposter.smartag.my/images/chicken_soup.jpg";
private static Bitmap downloadBitmap;
private static BitmapDrawable bitmapDrawable;
private static boolean largerImg = false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.main);
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
mNfcPendingIntent = PendingIntent.getActivity(this, 0,
new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
IntentFilter ndefDetected = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
try {
ndefDetected.addDataType("text/plain");
} catch (MalformedMimeTypeException e) { }
mNdefExchangeFilters = new IntentFilter[] { ndefDetected };
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
NdefMessage[] messages = getNdefMessages(getIntent());
byte[] payload = messages[0].getRecords()[0].getPayload();
ndefMsg = new String(payload);
setIntent(new Intent()); // Consume this intent.
}
ConnectivityManager connManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo mWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if(ndefMsg == null || ndefMsg.length() == 0)
{
startActivity(new Intent(MainActivity.this, MainMenu.class));
}
else
{
setContentView(R.layout.main);
if (mWifi.isConnected()) {
ndefMsg1 = ndefMsg;
new DownloadFilesTask().execute();
ndefMsg = null;
}
else
{
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setTitle("Attention");
dialog.setMessage("No Internet Connection. Please enable the wifi.");
dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton)
{
}
});
dialog.show();
}
}
}
private class DownloadFilesTask extends AsyncTask<Void, Void, Void> {
protected void onPostExecute(Void result) {
}
@Override
protected Void doInBackground(Void... params) {
try {
URL myFileUrl = new URL("http://sposter.smartag.my/images/chicken_soup.jpg");
HttpURLConnection conn= (HttpURLConnection)myFileUrl.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
downloadBitmap = BitmapFactory.decodeStream(is);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
ImageView image = (ImageView) findViewById(R.id.imview);
image.setImageBitmap(downloadBitmap);
return null;
}
}
}
回答by user370305
Bad practice of use of AsyncTask,
使用AsyncTask 的坏习惯,
You are trying to update your Main UI Thread from doInBackGround()
as AsyncTask never allowed that.
您正在尝试更新您的主 UI 线程,doInBackGround()
因为 AsyncTask 不允许这样做。
Never update your UI from doInBackGround()
of AsyncTask as its only worker thread. So write your Main UI updatation code in onPostExecute()
method of AsyncTask..
永远不要从doInBackGround()
AsyncTask更新您的 UI作为其唯一的工作线程。所以在onPostExecute()
AsyncTask 的方法中编写你的主 UI 更新代码..
@Override
protected Void doInBackground(Void... params) {
try {
URL myFileUrl = new URL("http://sposter.smartag.my/images/chicken_soup.jpg");
HttpURLConnection conn= (HttpURLConnection)myFileUrl.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
downloadBitmap = BitmapFactory.decodeStream(is);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
onPostExecute()
{
ImageView image = (ImageView) findViewById(R.id.imview);
image.setImageBitmap(downloadBitmap);
}
回答by Vipul Shah
will add some points to what @user370305 Said,
将为@user370305 所说的添加一些要点,
You can not touch UI Elements in non-ui thread.
您不能在非 ui 线程中触摸 UI 元素。
If you are using AsyncTask
doInBackground
is executed in non-ui thread so you can't access ImageView in that .
如果您使用的AsyncTask
doInBackground
是在非 ui 线程中执行的,则您无法在该线程中访问 ImageView。
You can access UI elements in onPreExecute
,onProgressUpdate
& onPostExcecute
.
您可以访问onPreExecute
, onProgressUpdate
& 中的UI 元素onPostExcecute
。