【问题标题】:Activity leaked window exception on Dialog.show() when starting a Fragment transaction from an Activity class从 Activity 类启动 Fragment 事务时 Dialog.show() 上的 Activity 泄漏窗口异常
【发布时间】:2015-05-23 06:58:13
【问题描述】:

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

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();

        }

    }
}

有人可以帮帮我吗?

谢谢!

【问题讨论】:

    标签: java android android-fragments android-dialog


    【解决方案1】:

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

    你应该在调用dismiss

    之后在onPostExecute中发布交易代码

    【讨论】:

    • 我该怎么做呢?
    • 我看到你依赖一个整数变量“成功”。您可以像 AsyncTask 一样声明您的异步任务,然后在 doInBackGround 中返回“成功”变量,该变量将由 onPostExecute 自动接收。然后你可以检查这个值并调用事务代码。
    • 我不再收到此错误,但是我现在收到“找不到 id 的视图”错误,这是问题的链接,请帮我看看。这里是link问题
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      您需要在 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();
      
          }
      });
      

      【讨论】:

      • 现在我收到一个错误 No view found for id 0x7f0900a3 (com.fitserv.androidapp:id/frame_container) for fragment UserWorkoutPlanFragment{40d0b748 #0 id=0x7f0900a3},你知道为什么这可能就是这样
      • @user3661128 这是一个不相关的错误。请再问一个问题。
      • 是的,我做到了,这里是link
      • @user3661128 ,如果发布的答案对您有帮助,只需单击作为最佳答案或仅投票为有帮助。我认为您确实进行了上面建议的代码更改。
      【解决方案4】:

      logcat报错中,有:

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

      所以问题出在 onPreExecute 方法上。我以前没有使用过 ProgressDialog,但问题出在 context 参数上。在这种情况下NewWorkout.this。这不是正确的上下文。

      代码建议:

      1. pDialog = new ProgressDialog(getApplicationContext());
      2. pDialog = new ProgressDialog(getActivity());
      3. pDialog = 新 ProgressDialog( MainActivity.this );

      注意:对于 MainActivity,如果声明为static,则可以使用此代码。 我认为主要问题是上下文

      仅供参考:有趣的是,发布的答案有些不同,但有些答案集中在对话上。

      【讨论】:

      • 我现在收到“找不到 id 的视图”错误,这是问题的链接,请帮我看看。这里是link问题
      猜你喜欢
      • 2017-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-19
      • 2015-08-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多