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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 04:13:36  来源:igfitidea点击:

android - Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException

javaandroidimageurl

提问by chinna_82

Possible Duplicate:
Android - ViewRootImpl$CalledFromWrongThreadException

可能重复:
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 AsyncTaskdoInBackgroundis executed in non-ui thread so you can't access ImageView in that .

如果您使用的AsyncTaskdoInBackground是在非 ui 线程中执行的,则您无法在该线程中访问 ImageView。

You can access UI elements in onPreExecute,onProgressUpdate& onPostExcecute.

您可以访问onPreExecute, onProgressUpdate& 中的UI 元素onPostExcecute