【问题标题】:Android crash in AsyncTaskAsyncTask 中的 Android 崩溃
【发布时间】:2015-06-17 20:14:03
【问题描述】:

当我运行我的项目并从显示项目所有内容的活动中运行 AsyncTask 时,APP 崩溃并显示以下错误消息:

06-17 20:56:52.856      418-428/? E/art﹕ Failed sending reply to debugger: Broken pipe
06-17 20:57:07.391      418-767/com.example.user.project_test E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #3
    Process: com.example.user.project_test, PID: 418
    java.lang.RuntimeException: An error occured while executing doInBackground()
            at android.os.AsyncTask$3.done(AsyncTask.java:304)
            at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
            at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
            at java.util.concurrent.FutureTask.run(FutureTask.java:242)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
            at java.lang.Thread.run(Thread.java:818)
     Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
            at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6357)
            at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:909)
            at android.view.ViewGroup.invalidateChild(ViewGroup.java:4690)
            at android.view.View.invalidateInternal(View.java:11801)
            at android.view.View.invalidate(View.java:11765)
            at android.view.View.invalidate(View.java:11749)
            at android.widget.TextView.checkForRelayout(TextView.java:6858)
            at android.widget.TextView.setText(TextView.java:4057)
            at android.widget.TextView.setText(TextView.java:3915)
            at android.widget.TextView.setText(TextView.java:3890)
            at com.example.user.project.itemActivity$getitem.doInBackground(itemActivity.java:132)
            at com.example.user.project.itemActivity$getitem.doInBackground(itemActivity.java:84)
            at android.os.AsyncTask$2.call(AsyncTask.java:292)
            at java.util.concurrent.FutureTask.run(FutureTask.java:237)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
            at java.lang.Thread.run(Thread.java:818)
06-17 20:57:07.612      418-418/com.example.user.project_test E/WindowManager﹕ android.view.WindowLeaked: Activity com.example.user.project.itemActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{19feb64d V.E..... R......D 0,0-1026,348} that was originally added here
            at android.view.ViewRootImpl.<init>(ViewRootImpl.java:363)
            at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:271)
            at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)
            at android.app.Dialog.show(Dialog.java:298)
            at com.example.user.project.itemActivity$getitem.onPreExecute(itemActivity.java:96)
            at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:591)
            at android.os.AsyncTask.execute(AsyncTask.java:539)
            at com.example.user.project.itemActivity.onCreate(itemActivity.java:71)
            at android.app.Activity.performCreate(Activity.java:5990)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
            at android.app.ActivityThread.access$800(ActivityThread.java:151)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5254)
            at java.lang.reflect.description.invoke(Native description)
            at java.lang.reflect.description.invoke(description.java:372)
            at com.android.internal.os.ZygoteInit$descriptionAndArgsCaller.run(ZygoteInit.java:903)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

我把我当前的代码放在这里

ItemActivity.java(它是在 AsyncTask 中崩溃的类:

public class ItemActivity extends AppCompatActivity {

    private static final String TAG_SUCCESS = "success";
    private static final String TAG_ITEM = "item";
    private static final String TAG_ITEM_NAME = "name";
    private static final String TAG_ITEM_description = "item";

    Integer item_id;
    String name;
    String username;
    String item;
    TextView itemname;
    TextView itemitem;
    ProgressDialog pDialog;
    JSONParser jParser;
    RecyclerView recycler;
    ActionBar actionBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_item);

        Intent i = getIntent();
        if (i.hasExtra("item_id")) {
            Bundle bd = getIntent().getExtras();
            /*if ((!bd.getString("name").equals(null) || bd.getString("name").trim().length() > 0) && (!bd.getString("username").equals(null) || bd.getString("username").trim().length() > 0) && (!bd.getString("description").equals(null) || bd.getString("description").trim().length() > 0)) {
                name = bd.getString("name");
                username = bd.getString("username");
                description = bd.getString("description");
            }*/
            item_id = bd.getInt("item_id");
        }

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        actionBar = getSupportActionBar();
        actionBar.setTitle(R.string.app_name);

        itemname = (TextView) findViewById(R.id.itemName);
        itemdescription = (TextView) findViewById(R.id.itemDescription);

        new getitem().execute();
        /*recycler = (RecyclerView) findViewById(R.id.recycler);
        recycler.setHasFixedSize(true);

        LinearLayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
        layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        recycler.setLayoutManager(layoutManager);*/

    }

    /**
     * Background Async Task to Get complete item details
     */
    class getitem extends AsyncTask<String, String, String> {

        /**
         * Before starting background thread Show Progress Dialog
         */
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            if (pDialog != null) {
                pDialog = null;
            }
            pDialog = new ProgressDialog(itemActivity.this);
            pDialog.setMessage(getResources().getString(R.string.loadingitem));
            pDialog.setIndeterminate(false);
            pDialog.setCancelable(false);
            pDialog.show();
        }

        /**
         * Getting item details in background thread
         */
        protected String doInBackground(String... params) {

            // updating UI from Background Thread

            // Check for success tag
            int success;
            try {
                // Building Parameters
                List<NameValuePair> myParameters = new ArrayList<NameValuePair>();
                myParameters.add(new BasicNameValuePair("item_id", Integer.toString(item_id)));

                // getting item details by making HTTP request
                // Note that item details url will use GET request
                jParser = new JSONParser();
                JSONObject json = jParser.makeHttpRequest(AppConfig.URL_GET_item, "GET", myParameters);

                // check your log for json response
                Log.d("Single item Details", json.toString());

                // json success tag
                success = json.getInt(TAG_SUCCESS);
                if (success == 1) {
                    // successfully received item details
                    JSONArray itemObj = json.getJSONArray(TAG_item); // JSON Array

                    // get first item object from JSON Array
                    JSONObject item = itemObj.getJSONObject(0);

                    // item with this pid found
                    // Edit Text
                    itemname.setText(item.getString(TAG_item_NAME));
                    itemdescription.setText(item.getString(TAG_item_description));
                } else {
                    // item with pid not found
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }

            return null;
        }

        /**
         * After completing background task Dismiss the progress dialog
         * *
         */
        protected void onPostExecute(String file_url) {
            // dismiss the dialog once got all details
            pDialog.dismiss();
        }
    }

    /*itemname=(TextView)

    findViewById(R.id.itemName);

    itemdescription=(TextView)

    findViewById(R.id.itemdescription);*/

    //itemname.setText(name);
    //itemdescription.setText(description);

}

activity_item.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/navigation_drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="@bool/fitsSystemWindows">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="@dimen/status_bar_height"
            android:background="?colorPrimary" />

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="@dimen/status_bar_height"
            android:background="?colorPrimaryDark" />

    </LinearLayout>

    <FrameLayout
        android:id="@+id/flma"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/status_bar_height">

        <TextView
            android:id="@+id/itemName"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal|top"
            android:layout_marginTop="80dp"
            android:gravity="center"
            android:textAllCaps="true"
            android:textSize="25dp"
            android:textStyle="bold" />

        <ImageView
            android:id="@+id/itemPhoto"
            android:layout_width="fill_parent"
            android:layout_height="300dp"
            android:layout_gravity="center"
            android:background="#000"
            android:src="@drawable/header" />

        <TextView
            android:id="@+id/itemdescription"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal|bottom"
            android:layout_marginBottom="50dp"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:text="Large Text"
            android:textAppearance="?android:attr/textAppearanceLarge" />

    </FrameLayout>

    <android.support.design.widget.NavigationView
        android:id="@+id/navigation_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="@bool/fitsSystemWindows"
        app:headerLayout="@layout/navigation_drawer_header"
        app:menu="@menu/navigation_drawer_menu"
        app:theme="@style/NavigationViewTheme" />

</android.support.v4.widget.DrawerLayout>

我正在搜索,我发现检查进度对话框是否不为 null 将其设置为 null 问题可以解决,但对我不起作用。

有人知道我在课堂上是否做错了吗?

谢谢!!

解决方案:

感谢 Itzik Samara 和 ligi 对问题的帮助和解释,我修复了问题,删除了 Itzik Samara 指示的行并在 onPostExecute 中添加以下代码:

protected void onPostExecute(String file_url) {
            // dismiss the dialog once got all details

            try {
                itemname.setText(item.getString(TAG_item_NAME));
            } catch (JSONException e) {
                e.printStackTrace();
            }
            try {
                itemdescription.setText(item.getString(TAG_item_description));
            } catch (JSONException e) {
                e.printStackTrace();
            }
            pDialog.dismiss();
        }

【问题讨论】:

    标签: java android android-activity android-asynctask progressdialog


    【解决方案1】:

    您不能在后台线程中触摸 UI 元素(例如 setText)。您可能想要包装在 runOnUIThread() 中或在 onPre / onPost 执行中执行这些操作(它们在 UI 线程上)并阅读有关 android 线程的信息

    【讨论】:

    • 谢谢!!正如我对 Itzik Samara 所说,我不知道这不能像我以前那样做。太感谢了!!我用解决方案编辑。
    • 不客气 - 你可以删除 if (pDialog != null) { pDialog = null; } 在这种情况下,这根本没有任何作用
    • 谢谢!我试过了,试图解决这个问题,我会删除它。
    【解决方案2】:

    你的问题是这两行:

    itemname.setText(item.getString(TAG_ITEM_NAME));
    itemdescription.setText(item.getString(TAG_ITEM_DESCRIPTION));
    

    2 个选择:

    1. 将数据发送到onPostExecute 并从那里更新EditText
    2. 使用 RunOnUiThread 并更新其中的 2 个 EditText

    【讨论】:

    • 谢谢!!我不知道这不能像我那样做。太感谢了!我用解决方案编辑。
    【解决方案3】:

    尝试将其添加到您的 doInBackground()

    runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    itemname.setText(item.getString(TAG_item_NAME));
                    itemdescription.setText(item.getString(TAG_item_description));
                }
    });
    

    或者把这两行放在onPostExecute()

    itemname.setText(item.getString(TAG_item_NAME));
    itemdescription.setText(item.getString(TAG_item_description));
    

    这是你的整个班级

    public class itemActivity extends AppCompatActivity {
    
    private static final String TAG_SUCCESS = "success";
    private static final String TAG_item = "item";
    private static final String TAG_item_NAME = "name";
    private static final String TAG_item_description = "description";
    
    Integer item_id;
    String name;
    String username;
    String description;
    TextView itemname;
    TextView itemdescription;
    ProgressDialog pDialog;
    JSONParser jParser;
    RecyclerView recycler;
    ActionBar actionBar;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_item);
    
        Intent i = getIntent();
        if (i.hasExtra("item_id")) {
            Bundle bd = getIntent().getExtras();
            /*if ((!bd.getString("name").equals(null) || bd.getString("name").trim().length() > 0) && (!bd.getString("username").equals(null) || bd.getString("username").trim().length() > 0) && (!bd.getString("description").equals(null) || bd.getString("description").trim().length() > 0)) {
                name = bd.getString("name");
                username = bd.getString("username");
                description = bd.getString("description");
            }*/
            item_id = bd.getInt("item_id");
        }
    
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
    
        actionBar = getSupportActionBar();
        actionBar.setTitle(R.string.app_name);
    
        itemname = (TextView) findViewById(R.id.itemName);
        itemdescription = (TextView) findViewById(R.id.itemdescription);
    
        new getitem().execute();
        /*recycler = (RecyclerView) findViewById(R.id.recycler);
        recycler.setHasFixedSize(true);
    
        LinearLayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
        layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        recycler.setLayoutManager(layoutManager);*/
    
    }
    
    /**
     * Background Async Task to Get complete item details
     */
    class getitem extends AsyncTask<String, String, String> {
    
        /**
         * Before starting background thread Show Progress Dialog
         */
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            if (pDialog != null) {
                pDialog = null;
            }
            pDialog = new ProgressDialog(itemActivity.this);
            pDialog.setMessage(getResources().getString(R.string.loadingitem));
            pDialog.setIndeterminate(false);
            pDialog.setCancelable(false);
            pDialog.show();
        }
    
        /**
         * Getting item details in background thread
         */
        protected String doInBackground(String... params) {
    
            // updating UI from Background Thread
    
            // Check for success tag
            int success;
            try {
                // Building Parameters
                List<NameValuePair> myParameters = new ArrayList<NameValuePair>();
                myParameters.add(new BasicNameValuePair("item_id", Integer.toString(item_id)));
    
                // getting item details by making HTTP request
                // Note that item details url will use GET request
                jParser = new JSONParser();
                JSONObject json = jParser.makeHttpRequest(AppConfig.URL_GET_item, "GET", myParameters);
    
                // check your log for json response
                Log.d("Single item Details", json.toString());
    
                // json success tag
                success = json.getInt(TAG_SUCCESS);
                if (success == 1) {
                    // successfully received item details
                    JSONArray itemObj = json.getJSONArray(TAG_item); // JSON Array
    
                    // get first item object from JSON Array
                    JSONObject item = itemObj.getJSONObject(0);
    
                    // item with this pid found
                    // Edit Text
                    runOnUiThread(new Runnable() {
                    @Override
                     public void run() {
                       itemname.setText(item.getString(TAG_item_NAME));
                       itemdescription.setText(item.getString(TAG_item_description));
                     }
                    });
                } else {
                    // item with pid not found
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
    
            return null;
        }
    
        /**
         * After completing background task Dismiss the progress dialog
         * *
         */
        protected void onPostExecute(String file_url) {
            // dismiss the dialog once got all details
            pDialog.dismiss();
        }
    }
    
    }
    

    【讨论】:

    • 谢谢!最后我解决了在 onPostExcute 代码中设置 TextView 内容的问题。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-08
    • 1970-01-01
    相关资源
    最近更新 更多