从Activity类启动Fragment事务时,Dialog.show()上的活动泄露窗口异常

时间:2015-05-22 19:31:19

标签: java android android-fragments android-dialog

当我点击CreateWorkout按钮时,它会转到UserWorkoutPlanFragment()中指定的片段FragmentTransaction类。但是当交易开始的那一刻我得到一个错误。 我收到这个错误:

05-22 19:23:35.873: E/WindowManager(1042): Activity com.fitserv.user.profilemenu.NewWorkout has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{4170dd80 V.E..... R.....ID 0,0-308,96} that was originally added here
05-22 19:23:35.873: E/WindowManager(1042): android.view.WindowLeaked: Activity com.fitserv.user.profilemenu.NewWorkout has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{4170dd80 V.E..... R.....ID 0,0-308,96} that was originally added here
05-22 19:23:35.873: E/WindowManager(1042):  at android.view.ViewRootImpl.<init>(ViewRootImpl.java:354)
05-22 19:23:35.873: E/WindowManager(1042):  at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:216)
05-22 19:23:35.873: E/WindowManager(1042):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
05-22 19:23:35.873: E/WindowManager(1042):  at android.app.Dialog.show(Dialog.java:281)
05-22 19:23:35.873: E/WindowManager(1042):  at com.fitserv.user.profilemenu.NewWorkout$NewWorkoutPlan.onPreExecute(NewWorkout.java:90)
05-22 19:23:35.873: E/WindowManager(1042):  at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:586)
05-22 19:23:35.873: E/WindowManager(1042):  at android.os.AsyncTask.execute(AsyncTask.java:534)
05-22 19:23:35.873: E/WindowManager(1042):  at com.fitserv.user.profilemenu.NewWorkout$1.onClick(NewWorkout.java:70)
05-22 19:23:35.873: E/WindowManager(1042):  at android.view.View.performClick(View.java:4204)
05-22 19:23:35.873: E/WindowManager(1042):  at android.view.View$PerformClick.run(View.java:17355)
05-22 19:23:35.873: E/WindowManager(1042):  at android.os.Handler.handleCallback(Handler.java:725)
05-22 19:23:35.873: E/WindowManager(1042):  at android.os.Handler.dispatchMessage(Handler.java:92)
05-22 19:23:35.873: E/WindowManager(1042):  at android.os.Looper.loop(Looper.java:137)
05-22 19:23:35.873: E/WindowManager(1042):  at android.app.ActivityThread.main(ActivityThread.java:5041)
05-22 19:23:35.873: E/WindowManager(1042):  at java.lang.reflect.Method.invokeNative(Native Method)
05-22 19:23:35.873: E/WindowManager(1042):  at java.lang.reflect.Method.invoke(Method.java:511)
05-22 19:23:35.873: E/WindowManager(1042):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
05-22 19:23:35.873: E/WindowManager(1042):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
05-22 19:23:35.873: E/WindowManager(1042):  at dalvik.system.NativeStart.main(Native Method)

这是我的代码:

public class NewWorkout extends Activity {

    // Progress Dialog
    private ProgressDialog pDialog;

    JSONParser jsonParser = new JSONParser();
    EditText inputWorkoutName;
    EditText inputWorkoutDate;
    EditText inputExceriseName;
    EditText inputSets;
    EditText inputKg;
    EditText inputReps;
    EditText inputNotes;


    // url to create new product
    private static String url_create_workout = "http://ec2-54-77-51-119.eu-west-1.compute.amazonaws.com/android_connect/create_workout.php";

    // JSON Node names
    private static final String TAG_SUCCESS = "success";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.user_addworkout);

        // Edit Text
        inputWorkoutName = (EditText) findViewById(R.id.inputWorkoutName);
        inputWorkoutDate = (EditText) findViewById(R.id.inputWorkoutDate);
        inputExceriseName = (EditText) findViewById(R.id.inputExceriseName);
        inputSets = (EditText) findViewById(R.id.inputSets);
        inputKg = (EditText) findViewById(R.id.inputKg);
        inputReps = (EditText) findViewById(R.id.inputReps);
        inputNotes = (EditText) findViewById(R.id.inputNotes);

        // Create button
        Button btnCreateWorkout = (Button) findViewById(R.id.btnCreateWorkout);
        // button click event
        btnCreateWorkout.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                // creating new product in background thread
                new NewWorkoutPlan().execute();
            }
        });
    }

    /**
     * Background Async Task to Create new product
     * */
    class NewWorkoutPlan extends AsyncTask<String, String, String> {

        /**
         * Before starting background thread Show Progress Dialog
         * */
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            pDialog = new ProgressDialog(NewWorkout.this);
            pDialog.setMessage("Creating Your Workout Plan..");
            pDialog.setIndeterminate(false);
            pDialog.setCancelable(true);
            pDialog.show();
        }

        /**
         * Creating product
         * */
        protected String doInBackground(String... args) {
            String workout_name = inputWorkoutName.getText().toString();
            String workout_date = inputWorkoutDate.getText().toString();
            String exercise_name = inputExceriseName.getText().toString();
            String sets = inputSets.getText().toString();
            String weight_kg = inputKg.getText().toString();
            String reps = inputReps.getText().toString();
            String notes = inputNotes.getText().toString();

            // Building Parameters
            List<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("workout_name", workout_name));
            params.add(new BasicNameValuePair("workout_date", workout_date));
            params.add(new BasicNameValuePair("exercise_name", exercise_name));
            params.add(new BasicNameValuePair("sets", sets));
            params.add(new BasicNameValuePair("weight_kg", weight_kg));
            params.add(new BasicNameValuePair("reps", reps));
            params.add(new BasicNameValuePair("notes", notes));

            // getting JSON Object
            // Note that create product url accepts POST method
            JSONObject json = jsonParser.makeHttpRequest(url_create_workout,
                    "POST", params);

            // check log cat fro response
            Log.d("Create Response", json.toString());

            // check for success tag
            try {
                int success = json.getInt(TAG_SUCCESS);

                if (success == 1) {
                    /**
                    // successfully created product
                    Intent i = new Intent(getApplicationContext(), UserProfileActivity.class);
                    startActivity(i);
                    //closing this screen
                    finish();
                    **/

                    Fragment newFragment = new UserWorkoutPlanFragment();
                      FragmentTransaction transaction = getFragmentManager().beginTransaction();
                       transaction.replace(R.id.frame_container, newFragment);
                        transaction.commit();

                    UserWorkoutPlanFragment fd = new UserWorkoutPlanFragment();
                      FragmentTransaction  ft = getFragmentManager().beginTransaction();
                                  ft.replace(R.id.frame_container, fd); 

                                 // content_frame is your FrameLayout container
                                  ft.addToBackStack(null);
                                  ft.commit();  

                } else {
                    // failed to create product
                }
            } 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 done
            pDialog.dismiss();

        }

    }
}

有人可以帮帮我吗?

谢谢!

4 个答案:

答案 0 :(得分:0)

pDialog导致窗口泄漏。这种情况正在发生,因为您正在doInBackground中执行片段事务并在onPostExecute上调用 dismiss 方法。

在调用解雇

后,您应该在onPostExecute中发布交易代码

答案 1 :(得分:0)

我知道你是Android新手,但也许你已经用其他语言开发了,不是吗?无论如何,您应该使用设计模式进行编码,并在自己的特定类中执行您想要执行的操作。这样做,你将避免许多错误。 看一下这个关于设计模式的网站:http://pt.slideshare.net/PedroVicenteGmezSnch/software-design-patterns-on-android

答案 2 :(得分:0)

您需要在UI线程中执行FragmentTransaction。可以通过调用doInBackground

runOnUiThread方法内完成
runOnUiThread(new Runnable() {
    @Override
    public void run() {
        Fragment newFragment = new UserWorkoutPlanFragment();
        FragmentTransaction transaction = getFragmentManager().beginTransaction();
        transaction.replace(R.id.frame_container, newFragment);
        transaction.commit();

        UserWorkoutPlanFragment fd = new UserWorkoutPlanFragment();
        FragmentTransaction ft = getFragmentManager().beginTransaction();
        ft.replace(R.id.frame_container, fd);

        // content_frame is your FrameLayout container
        ft.addToBackStack(null);
        ft.commit();

    }
});

答案 3 :(得分:0)

在logcat错误中,有:

  

在   com.fitserv.user.profilemenu.NewWorkout $ NewWorkoutPlan。的 onPreExecute (NewWorkout.java:90)   05-22 19:23:35.873:E / WindowManager(1042):at   android.os.AsyncTask.executeOnExecutor(AsyncTask.java:586)

问题出在 onPreExecute 方法上。我之前没有使用过ProgressDialog,但问题出在context参数上。在这种情况下OR Override Qt::ItemFlags MyTableView::flags(const QModelIndex& index) const { Qt::ItemFlags flags = QAbstractTableModel::flags(index); flags |= Qt::ItemIsEditable; return flags; } 。这不是正确的背景。

代码建议:

  1. pDialog = new ProgressDialog(getApplicationContext());
  2. pDialog = new ProgressDialog(getActivity());
  3. pDialog = new ProgressDialog(MainActivity.this);
  4. 注意:对于MainActivity,如果声明为NewWorkout.this,则可以使用此代码。 我认为,主要问题是上下文

    仅供参考:我觉得有趣的是,发布的答案有些不同,但有些人专注于对话。