“Activity has leaked window that was originally added here”

12,122
public void syncSQLiteMySQLDB() {
   // Create AsycHttpClient object
   AsyncHttpClient client = new AsyncHttpClient();
   // Http Request Params Object
   RequestParams params = new RequestParams();
   // Show ProgressBar
   prgDialog = new ProgressDialog(MainActivity.this);
   prgDialog.setMessage("Transferring Data from Remote MySQL DB and Syncing SQLite. Please wait...");
   prgDialog.setCancelable(false);
   prgDialog.show();

   // Make Http call to getusers.php
   client.post("http://download.grupsapte.ro/sinc/getusers.php", params, new AsyncHttpResponseHandler() {
           @Override
           public void onSuccess(String response) {

               // Update SQLite DB with response sent by getusers.php
               updateSQLite(response);
           }
           // When error occured
           @Override
           public void onFailure(int statusCode, Throwable error, String content) {
               // TODO Auto-generated method stub

               if (statusCode == 404) {
                   Toast.makeText(getApplicationContext(), "Requested resource not found", Toast.LENGTH_LONG).show();
               } else if (statusCode == 500) {
                   Toast.makeText(getApplicationContext(), "Something went wrong at server end", Toast.LENGTH_LONG).show();
               } else {
                   Toast.makeText(getApplicationContext(), "Unexpected Error occcured! [Most common Error: Device might not be connected to Internet]",
                           Toast.LENGTH_LONG).show();
               }
           }

            @Override
            public void onFinish(){
                // Hide ProgressBar
                if(prgDialog.isShowing())
               prgDialog.hide();
            }
   });

}

First of all you should declare local progress bar object and initialize with MainActivity.this also AsyncHttpClient have a method onFinish() which will call after success or failure called so you only need to hide your progress bar in onfinsh method and you always should check is progress bar is showing or not so it will not lead to generate excepetion

Share:
12,122
user1147188
Author by

user1147188

Updated on June 04, 2022

Comments

  • user1147188
    user1147188 almost 2 years

    I have the following code where I want to synchronize Mysql to SQLITE. The problem is that when I hit the synchronization button an error appears. The data is being transmited from the Mysql server to my SQLITE but it won't appear in the activity of my app where I put the data in a list.

    public class MainActivity extends ActionBarActivity {
        // DB Class to perform DB related operations
        DBController controller = new DBController(this);
        // Progress Dialog Object
        ProgressDialog prgDialog;
        HashMap<String, String> queryValues;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            // Get User records from SQLite DB
            ArrayList<HashMap<String, String>> userList = controller.getAllUsers();
            // If users exists in SQLite DB
            if (userList.size() != 0) {
                // Set the User Array list in ListView
                ListAdapter adapter = new SimpleAdapter(MainActivity.this, userList, R.layout.view_user_entry, new String[] {
                                "userId", "userName" }, new int[] { R.id.userId, R.id.userName });
                ListView myList = (ListView) findViewById(android.R.id.list);
                myList.setAdapter(adapter);
            }
            // Initialize Progress Dialog properties
            prgDialog = new ProgressDialog(this);
            prgDialog.setMessage("Transferring Data from Remote MySQL DB and Syncing SQLite. Please wait...");
            prgDialog.setCancelable(false);
            // BroadCase Receiver Intent Object
            Intent alarmIntent = new Intent(getApplicationContext(), SampleBC.class);
            // Pending Intent Object
            PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
            // Alarm Manager Object
            AlarmManager alarmManager = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
            // Alarm Manager calls BroadCast for every Ten seconds (10 * 1000), BroadCase further calls service to check if new records are inserted in 
            // Remote MySQL DB
            alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, Calendar.getInstance().getTimeInMillis() + 5000, 10 * 1000, pendingIntent);
        }
    
        // Options Menu (ActionBar Menu)
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.main, menu);
            return true;
        }
    
        // When Options Menu is selected
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            // Handle action bar item clicks here. 
            int id = item.getItemId();
            // When Sync action button is clicked
            if (id == R.id.refresh) {
                // Transfer data from remote MySQL DB to SQLite on Android and perform Sync
                syncSQLiteMySQLDB();
                return true;
            }
            return super.onOptionsItemSelected(item);
        }
    
        // Method to Sync MySQL to SQLite DB
        public void syncSQLiteMySQLDB() {
            // Create AsycHttpClient object
            AsyncHttpClient client = new AsyncHttpClient();
            // Http Request Params Object
            RequestParams params = new RequestParams();
            // Show ProgressBar
            prgDialog.show();
    
            // Make Http call to getusers.php
            client.post("http://download.grupsapte.ro/sinc/getusers.php", params, new AsyncHttpResponseHandler() {
                    @Override
                    public void onSuccess(String response) {
                        // Hide ProgressBar
                        prgDialog.hide();
                        // Update SQLite DB with response sent by getusers.php
                        updateSQLite(response);
                    }
                    // When error occured
                    @Override
                    public void onFailure(int statusCode, Throwable error, String content) {
                        // TODO Auto-generated method stub
                        // Hide ProgressBar
                        prgDialog.hide();
                        if (statusCode == 404) {
                            Toast.makeText(getApplicationContext(), "Requested resource not found", Toast.LENGTH_LONG).show();
                        } else if (statusCode == 500) {
                            Toast.makeText(getApplicationContext(), "Something went wrong at server end", Toast.LENGTH_LONG).show();
                        } else {
                            Toast.makeText(getApplicationContext(), "Unexpected Error occcured! [Most common Error: Device might not be connected to Internet]",
                                    Toast.LENGTH_LONG).show();
                        }
                    }
            });
        }
    
        public void updateSQLite(String response){
            ArrayList<HashMap<String, String>> usersynclist;
            usersynclist = new ArrayList<HashMap<String, String>>();
            // Create GSON object
            Gson gson = new GsonBuilder().create();
            try {
                // Extract JSON array from the response
                JSONArray arr = new JSONArray(response);
                System.out.println(arr.length());
                // If no of array elements is not zero
                if(arr.length() != 0){
                    // Loop through each array element, get JSON object which has userid and username
                    for (int i = 0; i < arr.length(); i++) {
                        // Get JSON object
                        JSONObject obj = (JSONObject) arr.get(i);
                        System.out.println(obj.get("userId"));
                        System.out.println(obj.get("userName"));
                        // DB QueryValues Object to insert into SQLite
                        queryValues = new HashMap<String, String>();
                        // Add userID extracted from Object
                        queryValues.put("userId", obj.get("userId").toString());
                        // Add userName extracted from Object
                        queryValues.put("userName", obj.get("userName").toString());
                        // Insert User into SQLite DB
                        controller.insertUser(queryValues);
                        HashMap<String, String> map = new HashMap<String, String>();
                        // Add status for each User in Hashmap
                        map.put("Id", obj.get("userId").toString());
                        map.put("status", "1");
                        usersynclist.add(map);
                    }
                    // Inform Remote MySQL DB about the completion of Sync activity by passing Sync status of Users
                    updateMySQLSyncSts(gson.toJson(usersynclist));
                    // Reload the Main Activity
                    reloadActivity();
                }
            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    
        // Method to inform remote MySQL DB about completion of Sync activity
        public void updateMySQLSyncSts(String json) {
            System.out.println(json);
            AsyncHttpClient client = new AsyncHttpClient();
            RequestParams params = new RequestParams();
            params.put("syncsts", json);
            // Make Http call to updatesyncsts.php with JSON parameter which has Sync statuses of Users
            client.post("http://download.grupsapte.ro/sinc/updatesyncsts.php", params, new AsyncHttpResponseHandler() {
                @Override
                public void onSuccess(String response) {
                    Toast.makeText(getApplicationContext(), "MySQL DB has been informed about Sync activity", Toast.LENGTH_LONG).show();
                }
    
                @Override
                public void onFailure(int statusCode, Throwable error, String content) {
                        Toast.makeText(getApplicationContext(), "Error Occured", Toast.LENGTH_LONG).show();
                }
            });
        }
    
        // Reload MainActivity
        public void reloadActivity() {
            Intent objIntent = new Intent(getApplicationContext(), MainActivity.class);
            startActivity(objIntent);
        }
    }
    

    And the error is the following:

    01-18 12:54:59.821: E/WindowManager(2022): android.view.WindowLeaked: Activity com.prgguru.example.MainActivity has leaked window com.android.internal.policy.PhoneWindow$DecorView{a19b187 G.E...... R.....ID 0,0-1336,384} that was originally added here
    01-18 12:54:59.821: E/WindowManager(2022):  at android.view.ViewRootImpl.<init>(ViewRootImpl.java:565)
    01-18 12:54:59.821: E/WindowManager(2022):  at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:326)
    01-18 12:54:59.821: E/WindowManager(2022):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
    01-18 12:54:59.821: E/WindowManager(2022):  at android.app.Dialog.show(Dialog.java:350)
    01-18 12:54:59.821: E/WindowManager(2022):  at com.prgguru.example.MainActivity.syncSQLiteMySQLDB(MainActivity.java:96)
    01-18 12:54:59.821: E/WindowManager(2022):  at com.prgguru.example.MainActivity.onOptionsItemSelected(MainActivity.java:83)
    01-18 12:54:59.821: E/WindowManager(2022):  at android.app.Activity.onMenuItemSelected(Activity.java:3204)
    01-18 12:54:59.821: E/WindowManager(2022):  at android.support.v4.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:353)
    01-18 12:54:59.821: E/WindowManager(2022):  at android.support.v7.app.ActionBarActivity.superOnMenuItemSelected(ActionBarActivity.java:244)
    01-18 12:54:59.821: E/WindowManager(2022):  at android.support.v7.app.ActionBarActivityDelegateICS.onMenuItemSelected(ActionBarActivityDelegateICS.java:165)
    01-18 12:54:59.821: E/WindowManager(2022):  at android.support.v7.app.ActionBarActivity.onMenuItemSelected(ActionBarActivity.java:130)
    01-18 12:54:59.821: E/WindowManager(2022):  at android.support.v7.app.ActionBarActivityDelegateICS$WindowCallbackWrapper.onMenuItemSelected(ActionBarActivityDelegateICS.java:300)
    01-18 12:54:59.821: E/WindowManager(2022):  at com.android.internal.policy.PhoneWindow.onMenuItemSelected(PhoneWindow.java:1259)
    01-18 12:54:59.821: E/WindowManager(2022):  at com.android.internal.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:801)
    01-18 12:54:59.821: E/WindowManager(2022):  at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:155)
    01-18 12:54:59.821: E/WindowManager(2022):  at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:954)
    01-18 12:54:59.821: E/WindowManager(2022):  at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:944)
    01-18 12:54:59.821: E/WindowManager(2022):  at android.widget.ActionMenuView.invokeItem(ActionMenuView.java:655)
    01-18 12:54:59.821: E/WindowManager(2022):  at com.android.internal.view.menu.ActionMenuItemView.onClick(ActionMenuItemView.java:251)
    01-18 12:54:59.821: E/WindowManager(2022):  at android.view.View.performClick(View.java:5697)
    01-18 12:54:59.821: E/WindowManager(2022):  at android.widget.TextView.performClick(TextView.java:10826)
    01-18 12:54:59.821: E/WindowManager(2022):  at android.view.View$PerformClick.run(View.java:22526)
    01-18 12:54:59.821: E/WindowManager(2022):  at android.os.Handler.handleCallback(Handler.java:739)
    01-18 12:54:59.821: E/WindowManager(2022):  at android.os.Handler.dispatchMessage(Handler.java:95)
    01-18 12:54:59.821: E/WindowManager(2022):  at android.os.Looper.loop(Looper.java:158)
    01-18 12:54:59.821: E/WindowManager(2022):  at android.app.ActivityThread.main(ActivityThread.java:7225)
    01-18 12:54:59.821: E/WindowManager(2022):  at java.lang.reflect.Method.invoke(Native Method)
    01-18 12:54:59.821: E/WindowManager(2022):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
    01-18 12:54:59.821: E/WindowManager(2022):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
    

    I know I should put a this.finish() somewhere but I don't know exactly where. Hope someone to help me.