android – 引发:android.view.ViewRootImpl $ CalledFromWrongThreadException

可能重复:
Android – ViewRootImpl $ CalledFromWrongThreadException

我试图从我的url获取图像,并显示在应用程序,但它会引发错误。 引起:android.view.ViewRootImpl $ CalledFromWrongThreadException:只有创build视图层次结构的原始线程可以触摸其视图 。 以下是我的代码

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://img.androidcookie.com/java/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://img.androidcookie.com/java/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; } } } 

使用AsyncTask的不好的做法,

你正在尝试从doInBackGround()更新你的主UI线程,因为AsyncTask永远不允许这样做。

切勿将AsyncTask的doInBackGround()更新为其唯一工作线程。 因此,在AsyncTask的onPostExecute()方法中编写主UI更新代码。

 @Override protected Void doInBackground(Void... params) { try { URL myFileUrl = new URL("http://img.androidcookie.com/java/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); } 

会加点什么@ user370305说,

您不能在非UI线程中触摸UI元素。

如果使用的是AsyncTask doInBackground是在非UI线程中执行的,所以你不能访问ImageView。

您可以访问onPreExecuteonProgressUpdateonPostExcecute UI元素。