Android泄露窗口 - 应用程序采用ANR状态

时间:2013-08-28 10:56:59

标签: android exception memory-leaks

我正在使用谷歌地图的Android应用程序。该应用程序最常使用。我能够在logcat [下面]中看到一些错误。

logcat的

08-28 15:37:36.945: E/WindowManager(21969): Activity com.kod.example.Find_Tab_MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@40929cd8 that was originally added here
08-28 15:37:36.945: E/WindowManager(21969): android.view.WindowLeaked: Activity com.kod.example.Find_Tab_MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@40929cd8 that was originally added here
08-28 15:37:36.945: E/WindowManager(21969):     at android.view.ViewRoot.<init>(ViewRoot.java:263)
08-28 15:37:36.945: E/WindowManager(21969):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:171)
08-28 15:37:36.945: E/WindowManager(21969):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:114)
08-28 15:37:36.945: E/WindowManager(21969):     at android.view.Window$LocalWindowManager.addView(Window.java:424)
08-28 15:37:36.945: E/WindowManager(21969):     at android.app.Dialog.show(Dialog.java:241)
08-28 15:37:36.945: E/WindowManager(21969):     at com.kod.example.MyProgressDialog.show(MyProgressDialog.java:36)
08-28 15:37:36.945: E/WindowManager(21969):     at com.kod.example.MyProgressDialog.show(MyProgressDialog.java:19)
08-28 15:37:36.945: E/WindowManager(21969):     at com.kod.example.MyProgressDialog.show(MyProgressDialog.java:14)
08-28 15:37:36.945: E/WindowManager(21969):     at com.kod.example.Find_Tab_MainActivity$LoadPlaces.onPreExecute(Find_Tab_MainActivity.java:129)
08-28 15:37:36.945: E/WindowManager(21969):     at android.os.AsyncTask.execute(AsyncTask.java:391)
08-28 15:37:36.945: E/WindowManager(21969):     at com.kod.example.Find_Tab_MainActivity.onCreate(Find_Tab_MainActivity.java:112)
08-28 15:37:36.945: E/WindowManager(21969):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
08-28 15:37:36.945: E/WindowManager(21969):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1615)
08-28 15:37:36.945: E/WindowManager(21969):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667)
08-28 15:37:36.945: E/WindowManager(21969):     at android.app.ActivityThread.access$1500(ActivityThread.java:117)
08-28 15:37:36.945: E/WindowManager(21969):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
08-28 15:37:36.945: E/WindowManager(21969):     at android.os.Handler.dispatchMessage(Handler.java:99)
08-28 15:37:36.945: E/WindowManager(21969):     at android.os.Looper.loop(Looper.java:130)
08-28 15:37:36.945: E/WindowManager(21969):     at android.app.ActivityThread.main(ActivityThread.java:3687)
08-28 15:37:36.945: E/WindowManager(21969):     at java.lang.reflect.Method.invokeNative(Native Method)
08-28 15:37:36.945: E/WindowManager(21969):     at java.lang.reflect.Method.invoke(Method.java:507)
08-28 15:37:36.945: E/WindowManager(21969):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
08-28 15:37:36.945: E/WindowManager(21969):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
08-28 15:37:36.945: E/WindowManager(21969):     at dalvik.system.NativeStart.main(Native Method)

这个泄露的窗户是什么?我的应用程序工作正常,但有时崩溃,总是抛出这个错误。

我的代码

package com.kod.example;

import java.util.List;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Address;
import android.location.Geocoder;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.Button;

import com.google.android.maps.MapActivity;


public class Find_Tab_MainActivity extends MapActivity {

    // flag for Internet connection status
    Boolean isInternetPresent = false;

    Geocoder geocoder;

    String status;

    // Connection detector class
    ConnectionDetector cd;

    // Alert Dialog Manager
    AlertDialogManager alert = new AlertDialogManager();

    // Google Places
    GooglePlaces googlePlaces;

    // Places List
    PlacesList nearPlaces;

    Place reference;
    // GPS Location
    GPSTracker gps;
    double latitude;
    double longitude;
    // Button
    Button loginbtn;

    Place p;

    Intent i;

    // Progress dialog
    ProgressDialog pDialog;
    final Context context = this;

    String type,KEY_KEYWORD,KEY_TAG;



    // KEY Strings
    public static String KEY_REFERENCE = "reference"; // id of the place
    public static String KEY_NAME = "name"; // name of the place
    public static String KEY_VICINITY = "vicinity";
    public static String KEY_NUMBER = "formatted_phone_number";


    // Place area name

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

        cd = new ConnectionDetector(getApplicationContext());


        Intent entent = getIntent();

           type = entent.getExtras().getString("KEY_TYPES");
           KEY_KEYWORD = entent.getExtras().getString("KEY_KEYWORD");
           KEY_TAG = entent.getExtras().getString("KEY_TAG");


        // Check if Internet present
        isInternetPresent = cd.isConnectingToInternet();
        if (!isInternetPresent) {
            // Internet Connection is not present
            alert.showAlertDialog(Find_Tab_MainActivity.this, "Internet Connection Error",
                    "Please connect to working Internet connection", false);
            // stop executing code by return
            return;
        }

        // creating GPS Class object
        gps = new GPSTracker(this);

        // check if GPS location can get
        if (gps.canGetLocation()) {

        } else {
            // Can't get user's current location
            alert.showAlertDialog(Find_Tab_MainActivity.this, "GPS Status",
                    "Couldn't get location information. Please enable GPS",
                    false);
            // stop executing code by return
            return;
        }


        // calling background Async task to load Google Places
        // After getting places from Google all the data is shown in listview
        new LoadPlaces().execute();

        /** Button click event for shown on map */

            }

    /**
     * Background Async Task to Load Google places
     * */
    class LoadPlaces extends AsyncTask<String, String, String> {

        /**
         * Before starting background thread Show Progress Dialog
         * */
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            MyProgressDialog.show(Find_Tab_MainActivity.this, "", ""); 
            }

        /**
         * getting Places JSON
         * */
        protected String doInBackground(String... args) {
            // creating Places class object
            googlePlaces = new GooglePlaces();

            try {
                // Separeate your place types by PIPE symbol "|"
                // If you want all types places make it as null
                // Check list of types supported by google
                String types = type; // Listing places only for park

                // Radius in meters - increase this value if you don't find any places
                double radius = 10000; // 1000 meters 

                if(KEY_TAG.equalsIgnoreCase("1")||KEY_TAG.equalsIgnoreCase("4")||KEY_TAG.equalsIgnoreCase("5"))
                {
                    // get nearest places
                    nearPlaces = googlePlaces.search(gps.getLatitude(),gps.getLongitude(), radius, types);
                }
                else if(KEY_TAG.equalsIgnoreCase("2")||KEY_TAG.equalsIgnoreCase("3"))
                {
                    // get nearest places
                    nearPlaces = googlePlaces.StreetGaragesearch(gps.getLatitude(), gps.getLongitude(), radius, types,KEY_KEYWORD); 
                }

                else if(KEY_TAG.equalsIgnoreCase("6"))
                {
                     String addressInput  = type;

                     geocoder = new Geocoder(Find_Tab_MainActivity.this);
                 List<Address> address;

                    address = geocoder.getFromLocationName(addressInput,1);
                         if (address == null) {
                             alert.showAlertDialog(Find_Tab_MainActivity.this, "Places Error",
                                        "Sorry error occured.",
                                        false);
                         }
                         else{
                         Address location = address.get(0);
                        latitude = location.getLatitude();
                        longitude = location.getLongitude();

                    nearPlaces = googlePlaces.Keywordsearch(latitude,longitude,radius+40000,"parking",type);
                         }

                    // get nearest places


            } 
            }
            catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        /**
         * After completing background task Dismiss the progress dialoghis
         * and show the data in UI
         * Always use runOnUiThread(new Runnable()) to update UI from background
         * thread, otherwise you will get error
         * **/
        @SuppressWarnings("deprecation")
        protected void onPostExecute(String file_url) {
            try{
        // Get json response status
             status = nearPlaces.status;

            // updating UI from Background Thread
            runOnUiThread(new Runnable() {
                public void run() {


                    if(status.equals("OK")){
                        // Successfully got places details
                        i = new Intent(getApplicationContext(),
                                MyPlacesMapActivity.class);
                        // Sending user current geo location

                        // passing near places to map activity
                        i.putExtra("near_places", nearPlaces);

                        //passing type to placemapactivity to identify the overlay icon
                        i.putExtra("KEY_TAG", KEY_TAG);

                        //passing place reference
                        i.putExtra("place_reference", reference);

                        // staring activity
                        startActivity(i);
                                }

                    else if(status.equals("ZERO_RESULTS")){
                        // Zero results found

                        final AlertDialog alertDialog = new AlertDialog.Builder(context).create();

                        // Setting Dialog Title
                        alertDialog.setTitle("No Results");

                        // Setting Dialog Message
                        alertDialog.setMessage("Sorry no places found. Try to change the location");

                        // Setting alert dialog icon
                            alertDialog.setIcon(R.drawable.fail);

                        // Setting OK Button
                        alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int which) {
                                Find_Tab_MainActivity.this.finish();
                            }
                        });

                        // Showing Alert Message
                        alertDialog.show();
                    }
                    else if(status.equals("UNKNOWN_ERROR"))
                    {

                        final AlertDialog alertDialog = new AlertDialog.Builder(context).create();

                        // Setting Dialog Title
                        alertDialog.setTitle("Error");

                        // Setting Dialog Message
                        alertDialog.setMessage("Sorry unknown error occured.");

                        // Setting alert dialog icon
                            alertDialog.setIcon(R.drawable.fail);

                        // Setting OK Button
                        alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int which) {
                                Find_Tab_MainActivity.this.finish();
                            }
                        });

                        // Showing Alert Message
                        alertDialog.show();

                    }
                    else if(status.equals("OVER_QUERY_LIMIT"))
                    {

                        final AlertDialog alertDialog = new AlertDialog.Builder(context).create();

                        // Setting Dialog Title
                        alertDialog.setTitle("Error");

                        // Setting Dialog Message
                        alertDialog.setMessage("Sorry query limit to is reached");

                        // Setting alert dialog icon
                            alertDialog.setIcon(R.drawable.fail);

                        // Setting OK Button
                        alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int which) {
                                Find_Tab_MainActivity.this.finish();
                            }
                        });

                        // Showing Alert Message
                        alertDialog.show();

                    }
                    else if(status.equals("REQUEST_DENIED"))
                    {

                        final AlertDialog alertDialog = new AlertDialog.Builder(context).create();

                        // Setting Dialog Title
                        alertDialog.setTitle("Error");

                        // Setting Dialog Message
                        alertDialog.setMessage("Sorry error occured. Request is denied");

                        // Setting alert dialog icon
                            alertDialog.setIcon(R.drawable.fail);

                        // Setting OK Button
                        alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int which) {
                                Find_Tab_MainActivity.this.finish();
                            }
                        });

                        // Showing Alert Message
                        alertDialog.show();

                    }
                    else if(status.equals("INVALID_REQUEST"))
                    {

                        final AlertDialog alertDialog = new AlertDialog.Builder(context).create();

                        // Setting Dialog Title
                        alertDialog.setTitle("Error");

                        // Setting Dialog Message
                        alertDialog.setMessage("Sorry error occured. Invalid Request");

                        // Setting alert dialog icon
                            alertDialog.setIcon(R.drawable.fail);

                        // Setting OK Button
                        alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int which) {
                                Find_Tab_MainActivity.this.finish();
                            }
                        });

                        // Showing Alert Message
                        alertDialog.show();
                    }
                    else
                    {

                        final AlertDialog alertDialog = new AlertDialog.Builder(context).create();

                        // Setting Dialog Title
                        alertDialog.setTitle("Error");

                        // Setting Dialog Message
                        alertDialog.setMessage("Sorry error occured.");

                        // Setting alert dialog icon
                            alertDialog.setIcon(R.drawable.fail);

                        // Setting OK Button
                        alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int which) {
                                Find_Tab_MainActivity.this.finish();
                            }
                        });

                        // Showing Alert Message
                        alertDialog.show();
                    }
                }
            });
        }catch(NullPointerException e){

            final AlertDialog alertDialog = new AlertDialog.Builder(context).create();

            // Setting Dialog Title
            alertDialog.setTitle("Error");

            // Setting Dialog Message
            alertDialog.setMessage("Requested place not found.");

            // Setting alert dialog icon
                alertDialog.setIcon(R.drawable.fail);

            // Setting OK Button
            alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    Find_Tab_MainActivity.this.finish();
                }
            });

            // Showing Alert Message
            alertDialog.show();

        }

        }
    }

    @Override
    protected boolean isRouteDisplayed() {
        // TODO Auto-generated method stub
        return false;
    }

}

3 个答案:

答案 0 :(得分:6)

What is this leaked window? 

您案件中的WindowLeaked exception正在发生,因为在完成活动之前您没有解雇MyProgressDialog。因此它泄漏了与之相关的记忆。

一般情况:

WindowLeaked exception通常会发生在某种异步任务在完成它的活动之后完成时被破坏。这种类型的异常发生在主要用于Dialogs的情况下,我们在这里在销毁活动上下文之前没有关闭对话框。

因此最好在显示对话框之前进行检查,如下所示:

if(getActivity()!= null && !getActivity().isFinishing()){
            Dialog.show();
}
上述问题的

解决方案是在完成活动之前dismiss MyProgressDialog

修改您的代码,如下所示:

protected void onPostExecute(String file_url) {

    // your first line should be this 

    if ( MyProgressDialog!=null && MyProgressDialog.isShowing() ){
        MyProgressDialog.dismiss();
    }

    // rest of the code 
}

答案 1 :(得分:2)

警报对话框出现问题。您不会在任何地方解雇您发起的对话框,也不会调用.dismiss()。同样仅供参考,您在runOnUiThread内不需要onPostExecute,因为此函数在UI线程本身中运行。

答案 2 :(得分:1)

在退出活动之前,在您创建的对话框上调用dismiss(),例如在onPause()