web-dev-qa-db-ja.com

アクティビティにより、最初にここに追加されたウィンドウcom.Android.internal.policy.impl.PhoneWindow$DecorView@44f72ff0がリークしました

私はGoogle Place APIを使用しており、最も近いレストランやカフェを取得したいのですが、プログレスバーを使用してそのデータを取得すると1つのエラーが発生します

class LoadPlaces extends AsyncTask<String, String, String> {

    /**
     * Before starting background thread Show Progress Dialog
     * */
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(MainActivity.this);
        pDialog.setMessage(Html.fromHtml("<b>Search</b><br/>Loading Places..."));
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(false);
        pDialog.show();
    }

    /**
     * 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 = "cafe|restaurant"; // Listing places only cafes, restaurants

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

            // get nearest places
            nearPlaces = googlePlaces.search(gps.getLatitude(),
                    gps.getLongitude(), radius, types);


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

 protected void onPostExecute(String file_url) {
        // dismiss the dialog after getting all products
        if(pDialog != null)
            pDialog.dismiss();
        // updating UI from Background Thread
        runOnUiThread(new Runnable() {
            public void run() {
                /**
                 * Updating parsed Places into LISTVIEW
                 * */
                // Get json response status
                String status = nearPlaces.status;

                // Check for all possible status
                if(status.equals("OK")){
                    // Successfully got places details
                    if (nearPlaces.results != null) {
                        // loop through each place
                        for (Place p : nearPlaces.results) {
                            HashMap<String, String> map = new HashMap<String, String>();

                            // Place reference won't display in listview - it will be hidden
                            // Place reference is used to get "place full details"
                            map.put(KEY_REFERENCE, p.reference);

                            // Place name
                            map.put(KEY_NAME, p.name);


                            // adding HashMap to ArrayList
                            placesListItems.add(map);
                        }
                        // list adapter
                        ListAdapter adapter = new SimpleAdapter(MainActivity.this, placesListItems,
                                R.layout.list_item,
                                new String[] { KEY_REFERENCE, KEY_NAME}, new int[] {
                                        R.id.reference, R.id.name });

                        // Adding data into listview
                        lv.setAdapter(adapter);
                    }
                }
                else if(status.equals("ZERO_RESULTS")){
                    // Zero results found
                    alert.showAlertDialog(MainActivity.this, "Near Places",
                            "Sorry no places found. Try to change the types of places",
                            false);
                }
                else if(status.equals("UNKNOWN_ERROR"))
                {
                    alert.showAlertDialog(MainActivity.this, "Places Error",
                            "Sorry unknown error occured.",
                            false);
                }
                else if(status.equals("OVER_QUERY_LIMIT"))
                {
                    alert.showAlertDialog(MainActivity.this, "Places Error",
                            "Sorry query limit to google places is reached",
                            false);
                }
                else if(status.equals("REQUEST_DENIED"))
                {
                    alert.showAlertDialog(MainActivity.this, "Places Error",
                            "Sorry error occured. Request is denied",
                            false);
                }
                else if(status.equals("INVALID_REQUEST"))
                {
                    alert.showAlertDialog(MainActivity.this, "Places Error",
                            "Sorry error occured. Invalid Request",
                            false);
                }
                else
                {
                    alert.showAlertDialog(MainActivity.this, "Places Error",
                            "Sorry error occured.",
                            false);
                }
            }
        });

    }

googlePlacesクラスの検索メソッドは

public PlacesList search(double latitude, double longitude, double radius, String types)
        throws Exception {

    this._latitude = latitude;
    this._longitude = longitude;
    this._radius = radius;

    try {

        HttpRequestFactory httpRequestFactory = createRequestFactory(HTTP_TRANSPORT);
        HttpRequest request = httpRequestFactory
                .buildGetRequest(new GenericUrl(PLACES_SEARCH_URL));
        request.getUrl().put("key", API_KEY);
        request.getUrl().put("location", _latitude + "," + _longitude);
        request.getUrl().put("radius", _radius); // in meters
        request.getUrl().put("sensor", "false");
        if(types != null)
            request.getUrl().put("types", types);



        PlacesList list = request.execute().parseAs(PlacesList.class);
        // Check log cat for places response status
        Log.d("Places Status", "" + list.status);
        return list;

    } catch (HttpResponseException e) {
        Log.e("Error:", e.getMessage());
        return null;
    }

}

そして、私は次のような許可を使用しました

しかし、私はlogcatでエラーが発生しています

08-14 22:29:59.867: E/AndroidRuntime(331): FATAL EXCEPTION: AsyncTask #1
08-14 22:29:59.867: E/AndroidRuntime(331): Java.lang.RuntimeException: An error occured    while executing doInBackground()
08-14 22:29:59.867: E/AndroidRuntime(331):  at Android.os.AsyncTask$3.done(AsyncTask.Java:200)
08-14 22:29:59.867: E/AndroidRuntime(331):  at Java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.Java:273)
08-14 22:29:59.867: E/AndroidRuntime(331):  at Java.util.concurrent.FutureTask.setException(FutureTask.Java:124)
08-14 22:29:59.867: E/AndroidRuntime(331):  at Java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.Java:307)
08-14 22:29:59.867: E/AndroidRuntime(331):  at Java.util.concurrent.FutureTask.run(FutureTask.Java:137)
08-14 22:29:59.867: E/AndroidRuntime(331):  at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1068)
08-14 22:29:59.867: E/AndroidRuntime(331):  at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:561)
08-14 22:29:59.867: E/AndroidRuntime(331):  at Java.lang.Thread.run(Thread.Java:1096)
08-14 22:29:59.867: E/AndroidRuntime(331): Caused by: Java.lang.NoClassDefFoundError: com.google.common.base.Preconditions
08-14 22:29:59.867: E/AndroidRuntime(331):  at com.google.api.client.util.ClassInfo.<init>(ClassInfo.Java:164)
08-14 22:29:59.867: E/AndroidRuntime(331):  at com.google.api.client.util.ClassInfo.of(ClassInfo.Java:92)
08-14 22:29:59.867: E/AndroidRuntime(331):  at com.google.api.client.util.GenericData.<init>(GenericData.Java:79)
08-14 22:29:59.867: E/AndroidRuntime(331):  at com.google.api.client.util.GenericData.<init>(GenericData.Java:61)
08-14 22:29:59.867: E/AndroidRuntime(331):  at com.google.api.client.http.GenericUrl.<init>(GenericUrl.Java:97)
08-14 22:29:59.867: E/AndroidRuntime(331):  at com.eheuristic.Android.googlemap.GooglePlaces.search(GooglePlaces.Java:56)
08-14 22:29:59.867: E/AndroidRuntime(331):  at com.eheuristic.Android.googlemap.MainActivity$LoadPlaces.doInBackground(MainActivity.Java:1 85)
08-14 22:29:59.867: E/AndroidRuntime(331):  at com.eheuristic.Android.googlemap.MainActivity$LoadPlaces.doInBackground(MainActivity.Java:1)
08-14 22:29:59.867: E/AndroidRuntime(331):  at Android.os.AsyncTask$2.call(AsyncTask.Java:185)
08-14 22:29:59.867: E/AndroidRuntime(331):  at Java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.Java:305)
08-14 22:29:59.867: E/AndroidRuntime(331):  ... 4 more
08-14 22:29:59.967: W/IInputConnectionWrapper(331): showStatusIcon on inactive InputConnection
08-14 22:30:02.298: E/WindowManager(331): Activity com.eheuristic.Android.googlemap.MainActivity has leaked window com.Android.internal.policy.impl.PhoneWindow$DecorView@44f72ff0 that was originally added here
08-14 22:30:02.298: E/WindowManager(331): Android.view.WindowLeaked: Activity com.eheuristic.Android.googlemap.MainActivity has leaked window com.Android.internal.policy.impl.PhoneWindow$DecorView@44f72ff0 that was originally added here
08-14 22:30:02.298: E/WindowManager(331):   at Android.view.ViewRoot.<init>(ViewRoot.Java:247)
08-14 22:30:02.298: E/WindowManager(331):   at Android.view.WindowManagerImpl.addView(WindowManagerImpl.Java:148)
08-14 22:30:02.298: E/WindowManager(331):   at Android.view.WindowManagerImpl.addView(WindowManagerImpl.Java:91)
08-14 22:30:02.298: E/WindowManager(331):   at Android.view.Window$LocalWindowManager.addView(Window.Java:424)
08-14 22:30:02.298: E/WindowManager(331):   at Android.app.Dialog.show(Dialog.Java:241)
08-14 22:30:02.298: E/WindowManager(331):   at com.eheuristic.Android.googlemap.MainActivity$LoadPlaces.onPreExecute(MainActivity.Java:164)
08-14 22:30:02.298: E/WindowManager(331):   at Android.os.AsyncTask.execute(AsyncTask.Java:391)
08-14 22:30:02.298: E/WindowManager(331):   at com.eheuristic.Android.googlemap.MainActivity.onCreate(MainActivity.Java:104)
08-14 22:30:02.298: E/WindowManager(331):   at Android.app.Instrumentation.callActivityOnCreate(Instrumentation.Java:1047)
08-14 22:30:02.298: E/WindowManager(331):   at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:2627)
08-14 22:30:02.298: E/WindowManager(331):   at Android.app.ActivityThread.handleLaunchActivity(ActivityThread.Java:2679)
08-14 22:30:02.298: E/WindowManager(331):   at Android.app.ActivityThread.access$2300(ActivityThread.Java:125)
08-14 22:30:02.298: E/WindowManager(331):   at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:2033)
08-14 22:30:02.298: E/WindowManager(331):   at Android.os.Handler.dispatchMessage(Handler.Java:99)
08-14 22:30:02.298: E/WindowManager(331):   at Android.os.Looper.loop(Looper.Java:123)
08-14 22:30:02.298: E/WindowManager(331):   at Android.app.ActivityThread.main(ActivityThread.Java:4627)
08-14 22:30:02.298: E/WindowManager(331):   at Java.lang.reflect.Method.invokeNative(Native Method)
08-14 22:30:02.298: E/WindowManager(331):   at Java.lang.reflect.Method.invoke(Method.Java:521)
08-14 22:30:02.298: E/WindowManager(331):   at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:868)
08-14 22:30:02.298: E/WindowManager(331):   at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:626)
08-14 22:30:02.298: E/WindowManager(331):   at dalvik.system.NativeStart.main(Native Method)
28
user1545066

ダイアログがリークしています。非同期タスクのonPostExecute()メソッドでpDialog.dismiss();を呼び出す必要があります。また、置く必要があります...

if(pDialog != null)
    pDialog.dismiss();

メインスレッドのアクティビティのonPause()メソッドで。これにより、アプリケーションがバックグラウンド実行中にフォアグラウンドを失っても、ウィンドウがリークしないようになります。このようなものがあるはずです...

public class Login extends Activity implements View.OnClickListener{

    ProgressDialog pd;

    public void onCreate(Bundle savedInstanceState){

        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
        setContentView(R.layout.login);
        pd = null;
    } 

    @Override
    public void onPause(){

        super.onPause();
        if(pd != null)
            pd.dismiss();
    }

    public void onClick(View v){
        new SendTask().execute("");
    }

    /*
    No networking allowed on the main thread.
    */
    private class SendTask extends AsyncTask<String,String,String>{

        int result;

        @Override
        protected void onPreExecute(){
            pd = ProgressDialog.show(Login.this,"","Retrieving Inbox...", true,false);
        }

        @Override
        protected String doInBackground(String...strings){

            //do networking here
            result = account.prepare();
            return null;
        }

        @Override
        protected void onPostExecute(String unused){

            //check result
            pd.dismiss();
            Intent intent = new Intent(Login.this,NextActivity.class);
            finish();
            startActivity(intent);
        }
     }
}
52
Joel

画面を終了した後、ダイアログウィンドウを表示しようとしています。

4
Pankaj Arora

これをonStopで使用します--->

@Override
    protected void onStop() {

        super.onStop();

        if (pDialog != null) {
            pDialog.dismiss();
            pDialog = null;
        }

    }
2
NRahman

アクティビティが破棄される前にダイアログを閉じる必要があります

@Override
protected void onDestroy() {
    super.onDestroy();
    if(pDialog!=null && pDialog.isShowing())
        pDialog.dismiss();
}
1
Naveed Ahmad

IsNetworkAvailable()関数でAsynctaskを呼び出すだけです...

if(isNetworkAvailable()) {
      AsyncTask_WebAPI asyncTask = new AsyncTask_WebAPI(this, strURL, this);
        asyncTask.execute();
    }else
    {
Toast.makeText(this,"Please Check internet Connectivity",Toast.LENGTH_LONG).show();
   }

IsNetworkAvailable()関数

private boolean isNetworkAvailable() {
    ConnectivityManager connectivityManager
            = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
    return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
0
Kishor N R