Navigation drawer takes time to open and close

1.3k views Asked by At

I have added navigation view and drawer layout in my app. When I open and close the drawer it lags in time. opens and close slowly. I got this issue prominently on version 4.4 also on 6.0 but not as prominently as 4.4.

When I am running on 4.4 device as I open the drawer I noticed messages in log that too much work may be doing on main thread.

So I tried to comment all the code except the navigation drawer and options menu code. So after that I found it was working bit well.

Is it the issue? or some memory issue can be there? But on larger memory devices also I found the problem.

Do I need to create another activity for other code? So that drawer will work faster?

I also tried to create a fragment and replaced it in framelayout of main activity to separate the code. But it was still lagging.

If I create new activity still I need all the navigation code in that activity, it will be again a same thing.

I am not getting what can be the issue. Can anyone please help.. Thank you..

Here is code:

public class MainActivity extends AppCompatActivity implements GetContactsAsyncTask.ContactGetCallBack,UpdateUserAsyncTask.UpdateUserCallBack {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        contactDb = new ContactTableHelper(MainActivity.this);
        mDb = new UserTableHelper(MainActivity.this);

        boolean result = Utility.checkAndRequestPermissions(MainActivity.this);

        LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver,
                new IntentFilter(REGISTRATION_COMPLETE));
        LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver,
                new IntentFilter(PUSH_NOTIFICATION));

        NotificationUtils.clearNotifications(getApplicationContext());


        sharedpreferences = getSharedPreferences("UserProfile", Context.MODE_PRIVATE);

        mUserId = sharedpreferences.getString("userId", "");

        firstTimeLogin = sharedpreferences.getBoolean("login", false);

        refreshedToken = sharedpreferences.getString("deviceId", "");

        parentLayout = (LinearLayout) findViewById(R.id.toolbar_container);

        setupView();

        mUser = new User();

        url = sharedpreferences.getString("url", "");

        contactList = new ArrayList<Contact>();

        txtuserName = (TextView) findViewById(R.id.txtusername);
        txtmobile = (TextView) findViewById(R.id.txtmobile);
        profileImageView = (CircleImageView) findViewById(R.id.thumbnail);

        if (profileImageView != null) {
            profileImageView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    drawerLayout.closeDrawers();
                    Intent Intent = new Intent(MainActivity.this, ProfileActivity.class);
                    Intent.putExtra("user", mUser);
                    Intent.putExtra("url", url);
                    startActivity(Intent);
                }
            });
        }

        BitmapFactory.Options bmOptions = new BitmapFactory.Options();
        Bitmap bitmap = BitmapFactory.decodeFile(image.getPath(), bmOptions);

        if (bitmap != null) {
            profileImageView.setImageBitmap(bitmap);
        } else {
            profileImageView.setImageDrawable(ContextCompat.getDrawable(MainActivity.this, R.drawable.ic_account_circle_white_48dp));
        }

        ImageView sync = (ImageView) findViewById(R.id.sync);

        sync.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                contactList.clear();
                contactDb.deleteAllContacts();

                GetContactsAsyncTask getContactsAsyncTask = new GetContactsAsyncTask(MainActivity.this, MainActivity.this, mUserId, MainActivity.this);
                getContactsAsyncTask.execute(mUserId);

            }
        });
    }

    void setupView() {
        File sd = Environment.getExternalStorageDirectory();
        image = new File(sd + "/Profile", "Profile_Image.png");

        drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

        navigationView = (NavigationView) findViewById(R.id.navigation_view);


        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {

            @Override
            public boolean onNavigationItemSelected(MenuItem menuItem) {
                drawerLayout.closeDrawers();
                menuItem.setChecked(true);

                FragmentManager fragmentManager = getSupportFragmentManager();

                switch (menuItem.getItemId()) {

                    case R.id.nav_menu_contacts:
                       fragmentManager.beginTransaction().replace(R.id.container, fragment).commit();

                        break;

                    case R.id.nav_menu_settings:

                        Intent i = new Intent(MainActivity.this, PreferencesActivity.class);
                        i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
                        startActivity(i);

                        break;

                    case R.id.nav_log_out:

                        SharedPreferences pref = getSharedPreferences("UserProfile", MODE_PRIVATE);
                        SharedPreferences.Editor editor = pref.edit();
                        editor.remove("UserUsername");
                        editor.remove("userId");
                        editor.remove("url");
                        editor.remove("login");
                        editor.remove("company");
                        editor.remove("emailId");
                        editor.remove("profileImage");
                        editor.remove("fullName");
                        editor.remove("homeAddress");
                        editor.remove("workAddress");
                        editor.remove("workPhone");
                        editor.remove("pass");
                        editor.remove("jobTitle");
                        editor.remove("mobileNo");
                        editor.commit();

                        mDb.deleteAllUsers();
                        contactDb.deleteAllContacts();
                        UpdateTokenAsyncTask updateTokenAsyncTask = new UpdateTokenAsyncTask(MainActivity.this, mUserId, "");
                        updateTokenAsyncTask.execute(mUserId, "");

                        finish();
                        i = new Intent(MainActivity.this, LoginActivity.class);
                        i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
                        i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
                        startActivity(i);

                        break;

                    case R.id.nav_invite:

                        i = new Intent(MainActivity.this, InviteContactsActivity.class);
                        i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
                        startActivity(i);

                        break;
                }
                return true;
            }
        });

        Toolbar toolbar = (Toolbar) findViewById(R.id.main_toolbar);
        TextView mTitle = (TextView) findViewById(R.id.toolbar_title);

        final ImageView menu = (ImageView) findViewById(R.id.menu);

        menu.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                PopupMenu popup = new PopupMenu(MainActivity.this, menu);

                popup.getMenuInflater().inflate(R.menu.main_pop_up_menu, popup.getMenu());

                popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                    public boolean onMenuItemClick(MenuItem item) {


                        if (item.getItemId() == R.id.pendingInvites) {

                            startActivity(new Intent(MainActivity.this, PendingInvitesActivity.class));

                        } else if (item.getItemId() == R.id.feedback) {
                            final MaterialDialog dialog = new MaterialDialog.Builder(MainActivity.this)
                                    .title("Feedback")
                                    .customView(R.layout.feedback_dialog, true).build();

                            positiveAction = dialog.getActionButton(DialogAction.POSITIVE);

                            edtName = (EditText) dialog.getCustomView().findViewById(R.id.editName);
                            edtEmailId = (EditText) dialog.getCustomView().findViewById(R.id.editTextEmailId);
                            edtComment = (EditText) dialog.getCustomView().findViewById(R.id.editTextComment);
                            buttonSave = (Button) dialog.getCustomView().findViewById(R.id.buttonSave);

                            buttonSave.setOnClickListener(new View.OnClickListener() {
                                @Override
                                public void onClick(View view) {
                                    View view1 = getCurrentFocus();
                                    if (view1 != null) {
                                        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                                        imm.hideSoftInputFromWindow(view1.getWindowToken(), 0);
                                    }
                                    mName = String.valueOf(edtName.getText().toString());

                                    mEmailId = String.valueOf(edtEmailId.getText().toString());

                                    mComment = String.valueOf(edtComment.getText().toString());

                                    if (mComment.equals("")) {

                                        showAlert("Please enter comments.");

                                    } else if (mEmailId.equals("")) {

                                        showAlert("Please enter an email-id.");

                                    } else {

                                        if (!isValidEmail(mEmailId)) {

                                            showAlert("Please enter valid email id.");

                                        } else {

                                            HashMap<String, String> params = new HashMap<String, String>();

                                            params.put("name", mName);
                                            params.put("email_id", mEmailId);
                                            params.put("comment", mComment);

                                            CreateFeedbackAsyncTask createFeedbackAsyncTask = new CreateFeedbackAsyncTask(MainActivity.this, MainActivity.this);
                                            createFeedbackAsyncTask.execute(params);

                                            dialog.dismiss();

                                        }
                                    }

                                }
                            });

                            edtName.addTextChangedListener(new TextWatcher() {
                                @Override
                                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                                }

                                @Override
                                public void onTextChanged(CharSequence s, int start, int before, int count) {
                                    positiveAction.setEnabled(s.toString().trim().length() > 0);


                                }

                                @Override
                                public void afterTextChanged(Editable s) {
                                    View view = getCurrentFocus();
                                    if (view != null) {
                                        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                                        imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
                                    }
                                }
                            });

                            edtComment.addTextChangedListener(new TextWatcher() {
                                @Override
                                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                                }

                                @Override
                                public void onTextChanged(CharSequence s, int start, int before, int count) {
                                    positiveAction.setEnabled(s.toString().trim().length() > 0);
                                    View view = getCurrentFocus();
                                    if (view != null) {
                                        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                                        imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
                                    }

                                }

                                @Override
                                public void afterTextChanged(Editable s) {
                                }
                            });

                            edtEmailId.addTextChangedListener(new TextWatcher() {
                                @Override
                                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                                }

                                @Override
                                public void onTextChanged(CharSequence s, int start, int before, int count) {
                                    positiveAction.setEnabled(s.toString().trim().length() > 0);
                                    View view = getCurrentFocus();
                                    if (view != null) {
                                        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                                        imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
                                    }

                                }

                                @Override
                                public void afterTextChanged(Editable s) {
                                }
                            });


                            dialog.show();
                            positiveAction.setEnabled(false);

                            return true;
                        }

                        return true;
                    }

                });

                popup.show();//showing popup menu
            }
        });


        if (toolbar != null) {
            toolbar.setTitle("");
            setSupportActionBar(toolbar);

        }

        if (toolbar != null) {

            toolbar.setNavigationIcon(R.drawable.ic_menu_white_24dp);
            toolbar.setNavigationOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    drawerLayout.openDrawer(GravityCompat.START);

                }
            });
        }
    }

    @Override
    public void doPostExecute(JSONArray response) throws JSONException {

        contactListArray = response;

        contactDb = new ContactTableHelper(MainActivity.this);

        if (null == contactList) {
            contactList = new ArrayList<Contact>();
        }

        for (int i = 0; i < contactListArray.length(); i++) {
            JSONObject subObject1 = contactListArray.getJSONObject(i);

            Contact contact = new Contact();
            JSONObject subObject = subObject1;
            String contactName = subObject.getString("user_name");
            //name of the attribute in response
            String pass = subObject.getString("password");
            String contactId = subObject.getString("user_id");
            String contactMobile = subObject.getString("mobile_no");
            String contactEmailId = subObject.getString("email_id");
            String contactProfile = subObject.getString("profile_image");
            String fullName = subObject.getString("full_name");
            String jobTitle = subObject.getString("job_title");
            String homeAddress = subObject.getString("home_address");
            String workPhone = subObject.getString("work_phone");
            String workAddress = subObject.getString("work_address");
            String company = subObject.getString("company");

            contact.setmThumbnail(contactProfile);
            contact.setmUserName(contactName);
            contact.setmMobileNo(contactMobile);
            contact.setmEmailId(contactEmailId);
            contact.setmProfileImage(contactProfile);
            contact.setContactId(contactId);
            contact.setmHomeAddress(homeAddress);
            contact.setmFullName(fullName);
            contact.setmJobTitle(jobTitle);
            contact.setmWorkAddress(workAddress);
            contact.setmWorkPhone(workPhone);
            contact.setmPass(pass);
            contact.setmCompany(company);

            contactList.add(contact);//adding string to arraylist

            contactDb.addContact(new Contact(contactId, contactName, pass, contactMobile, contactEmailId, contactProfile, fullName, jobTitle, workAddress, workPhone, homeAddress, company));

        }

        adapter = new ContactAdapter(MainActivity.this, contactList);
        recyclerView.setAdapter(adapter);
        recyclerView.setHasFixedSize(true);
        recyclerView.setItemViewCacheSize(20);
        recyclerView.setDrawingCacheEnabled(true);
        recyclerView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
    }

    @Override
    public void onResume() {
        super.onResume();

        contactList.clear();

        if (!firstTimeLogin) {
            contactList.clear();
            contactList = contactDb.getAllContacts();
            mUser = mDb.getUser(mUserId);

            txtuserName.setText(mUser.getmUserName());
            txtmobile.setText(mUser.getmMobileNo());
        } else {
            new GetUserAsyncTask1(MainActivity.this,mUserId).execute(mUserId);
            new GetContactsAsyncTask(this, MainActivity.this, mUserId, MainActivity.this).execute();

            firstTimeLogin = false;

            SharedPreferences.Editor editor = getSharedPreferences("UserProfile", MODE_PRIVATE).edit();
            editor.putBoolean("login", firstTimeLogin);
            editor.commit();
        }

        recyclerView = (RecyclerView) findViewById(R.id.recycler_view);

        recyclerView.setHasFixedSize(true);
        RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(MainActivity.this);
        recyclerView.setLayoutManager(mLayoutManager);
        recyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));
        recyclerView.setItemAnimator(new DefaultItemAnimator());

        adapter = new ContactAdapter(MainActivity.this, contactList);
        recyclerView.setAdapter(adapter);

        recyclerView.addOnItemTouchListener(new RecyclerTouchListener(MainActivity.this, recyclerView, new ClickListener() {
            @Override
            public void onClick(View view, int position) {
                final Contact contact = contactList.get(position);

            }

            @Override
            public void onLongClick(View view, int position) {

            }
        }));

    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case REQUEST_ID_MULTIPLE_PERMISSIONS: {
                Map<String, Integer> perms = new HashMap<String, Integer>();

                perms.put(Manifest.permission.WRITE_EXTERNAL_STORAGE, PackageManager.PERMISSION_GRANTED);
                perms.put(Manifest.permission.CAMERA, PackageManager.PERMISSION_GRANTED);
                perms.put(Manifest.permission.READ_CONTACTS, PackageManager.PERMISSION_GRANTED);
                perms.put(Manifest.permission.SEND_SMS, PackageManager.PERMISSION_GRANTED);

                for (int i = 0; i < permissions.length; i++)
                    perms.put(permissions[i], grantResults[i]);

                if (perms.get(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
                        && perms.get(Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED
                        && perms.get(Manifest.permission.SEND_SMS) == PackageManager.PERMISSION_GRANTED
                        && perms.get(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {


                } else {

                    showAlert("Some Permissions are Denied.");
                }    
            }
            break;
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

    @Override
    public void doPostExecute(JSONObject response, Boolean update) throws JSONException {


    }
}

Main layout :

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/container">
</FrameLayout>

<!-- Your normal content view -->
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:id = "@+id/toolbar_container">

    <!-- We use a Toolbar so that our drawer can be displayed
         in front of the action bar -->
    <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/main_toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
        <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="match_parent">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/Contacts"
            android:layout_gravity="center"
            android:id="@+id/toolbar_title"
            android:textSize="20sp"
            android:textColor="#ffffff"
            android:textStyle="bold"
            android:textAlignment="center"
            android:gravity="center_vertical|center|center_horizontal"
            android:layout_toLeftOf="@+id/sync"
            android:layout_toStartOf="@+id/sync"
            android:layout_centerInParent="true"
            android:layout_marginLeft="30dp"
            android:layout_marginRight="10dp" />


        <ImageView
            android:layout_width="24dp"
            android:layout_height="24dp"
            android:background="@drawable/ic_refresh_white_24dp"
            android:id="@+id/sync"
            android:layout_gravity = "right"
            android:layout_toStartOf="@+id/menu"
            android:layout_toLeftOf="@+id/menu"
            android:layout_centerVertical="true"
            android:layout_alignParentRight="false"
            android:layout_marginRight="10dp" />

        <ImageView
            android:layout_width="24dp"
            android:layout_height="24dp"
            android:layout_gravity= "end"
            android:layout_marginRight="10dp"
            android:background="@drawable/ic_more_vert_white_36dp"
            android:id="@+id/menu"
            android:layout_alignParentEnd="true"
            android:layout_centerVertical="true"
            android:layout_alignParentRight="true" />
        </RelativeLayout>
    </android.support.v7.widget.Toolbar>

    <view
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#ffffff"
        class="android.support.v7.widget.RecyclerView"
        android:id="@+id/recycler_view"
        android:layout_alignParentStart="true"
        android:layout_alignParentLeft="true" />
    <!-- The rest of your content view -->

</LinearLayout>



<android.support.design.widget.NavigationView
    android:id="@+id/navigation_view"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:background="?attr/colorPrimary"
    app:headerLayout="@layout/drawer_header"
    app:itemTextColor="@color/yourColor"
    app:itemIconTint="@color/yourColor"
    app:menu="@menu/nav_menu" >
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <include
            layout="@layout/drawer_header"
            android:layout_width="match_parent"
            android:layout_height="103dp" />

        <ExpandableListView

            android:id="@+id/elvGuideNavigation"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:groupIndicator="@null"
            />

    </LinearLayout>

</android.support.design.widget.NavigationView>

2

There are 2 answers

9
Hasif Seyd On BEST ANSWER

Do the Json Parsing and adding the Entries into the DB also in Background Thread and Pass only the ArrayList of Entries to the Main Thread, this way you can reduce the Load on the Main Thread.

Another thing you can try is Enabling hardwareAcceleration to true

2
Alexandru Dascălu On

Definitely try to move any database operations on another threads. Decoding that bitmap in onCreate() also is dangerous.

Maybe organising your code will help a bit.