应用程序可能在其主线程(导航抽屉)上做了太多工作

时间:2015-07-22 01:07:49

标签: java android multithreading navigation-drawer slowdown

我是java的新手,我收到了一个无法修复的错误。 我的应用程序正在使用导航抽屉,当我打开它时,应用程序变得非常慢,并且logcat显示跳帧的消息,应用程序可能在其主线程上做了太多工作......

不知道如何解决这个问题。 这是抽屉被调用的代码的一部分。

public class MainActivity extends SwipeRefreshActivity implements
    LocationListener, GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener {

private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private View mPanelMenu;
private ActionBarDrawerToggle mDrawerToggle;
// nav drawer title
private CharSequence mDrawerTitle;
// used to store app title
private CharSequence mTitle;
private Menu[] MENUS;
public static Location location;
public static List<Address> address;
public static int offsetY = 0;

private static SQLiteDatabase db;
private static DbHelper dbHelper;
private static Queries q;
protected static ImageLoader imageLoader;
private static boolean isShownSplash = false;

private LocationRequest mLocationRequest;
private GoogleApiClient mGoogleApiClient;
boolean mUpdatesRequested = false;

// Handle to SharedPreferences for this app
SharedPreferences mPrefs;

// Handle to a SharedPreferences editor
SharedPreferences.Editor mEditor;
private Fragment currFragment;

private GetAddressTask getAddressTask;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
    this.getActionBar().setIcon(R.drawable.header_logo);
    this.getActionBar().setTitle("");

    dbHelper = new DbHelper(this);
    q = new Queries(db, dbHelper);

    imageLoader = ImageLoader.getInstance();
    imageLoader.init(ImageLoaderConfiguration
            .createDefault(getBaseContext()));

    statusCallback = new SessionStatusCallback();
    mTwitter = new TwitterApp(this, twitterAppListener);

    mTitle = mDrawerTitle = "";
    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    mDrawerList = (ListView) findViewById(R.id.list_slidermenu);
    mPanelMenu = findViewById(R.id.panel_slidermenu);

    mDrawerList.setOnItemClickListener(new SlideMenuClickListener());
    mDrawerList.setDividerHeight(0);

    updateMenuList();

    // enabling action bar app icon and behaving it as toggle button
    getActionBar().setDisplayHomeAsUpEnabled(true);
    getActionBar().setHomeButtonEnabled(true);

    mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
            R.drawable.ic_menu, // nav
                                // menu
                                // toggle
                                // icon
            R.string.no_name, // nav drawer open - description for
                                // accessibility
            R.string.no_name // nav drawer close - description for
                                // accessibility
    ) {
        public void onDrawerClosed(View view) {
            getActionBar().setTitle(mTitle);
            // calling onPrepareOptionsMenu() to show action bar icons
            invalidateOptionsMenu();
        }

        public void onDrawerOpened(View drawerView) {
            getActionBar().setTitle(mDrawerTitle);
            // calling onPrepareOptionsMenu() to hide action bar icons
            invalidateOptionsMenu();
        }
    };
    mDrawerLayout.setDrawerListener(mDrawerToggle);

    TypedValue tv = new TypedValue();
    if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
        offsetY = TypedValue.complexToDimensionPixelSize(tv.data,
                getResources().getDisplayMetrics());
    }

    if (!isShownSplash) {
        isShownSplash = true;
        this.getActionBar().hide();
        FragmentManager fragmentManager = this.getSupportFragmentManager();
        fragmentManager.beginTransaction()
                .replace(R.id.frame_container, new SplashFragment())
                .commit();
    }

    else if (savedInstanceState == null) {
        // on first time display view for first nav item
        displayView(1);
    }

    mUpdatesRequested = false;

    // Open Shared Preferences
    mPrefs = getSharedPreferences(LocationUtils.SHARED_PREFERENCES,
            Context.MODE_PRIVATE);
    // Get an editor
    mEditor = mPrefs.edit();

    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addApi(LocationServices.API).addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this).build();

    FrameLayout frameAds = (FrameLayout) findViewById(R.id.frameAds);
    frameAds.setVisibility(View.GONE);

    if (MGUtilities.hasConnection(this)) {
        q.deleteTable("stores");
        q.deleteTable("categories");
        q.deleteTable("photos");
        q.deleteTable("reviews");
        q.deleteTable("ratings");
        q.deleteTable("news");
    }
}

public void showMainView() {
    getActionBar().show();
    displayView(1);
    showAds();
}

private class SlideMenuClickListener implements
        ListView.OnItemClickListener {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position,
            long id) {
        // display view for selected nav drawer item
        displayView(position);
    }
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // toggle nav drawer on selecting action bar app icon/title
    if (mDrawerToggle.onOptionsItemSelected(item)) {
        updateMenuList();
        return true;
    }
    // Handle action bar actions click
    switch (item.getItemId()) {
    // case R.id.action_settings:
    // return true;
    default:
        return super.onOptionsItemSelected(item);
    }
}

@Override
public boolean onCreateOptionsMenu(android.view.Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
}

@Override
public boolean onPrepareOptionsMenu(android.view.Menu menu) {
    // if nav drawer is opened, hide the action items
    // boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
    // menu.findItem(R.id.action_settings).setVisible(!drawerOpen);
    return super.onPrepareOptionsMenu(menu);
}

private void displayView(int position) {

    // clear back stack
    FragmentManager fm = this.getSupportFragmentManager();
    for (int i = 0; i < fm.getBackStackEntryCount(); ++i) {
        fm.popBackStackImmediate(null,
                FragmentManager.POP_BACK_STACK_INCLUSIVE);
    }

    // update the main content by replacing fragments
    Fragment fragment = null;
    switch (position) {

    case 1:
        fragment = new HomeFragment();
        break;
    case 2:
        fragment = new CategoryFragment();
        break;
    case 3:
        fragment = new FavoriteFragment();
        break;
    case 4:
        fragment = new FeaturedFragment();
        break;
    case 5:
        fragment = new MapFragment();
        break;
    case 6:
        fragment = new SearchFragment();
        break;
    case 7:
        fragment = new NewsFragment();
        break;
    case 8:
        fragment = new WeatherFragment();
        break;

    case 10:
        fragment = new AboutUsFragment();
        break;
    case 11:
        fragment = new TermsConditionFragment();
        break;

    case 13:

        UserAccessSession session = UserAccessSession.getInstance(this);
        if (session.getUserSession() == null) {
            Intent i = new Intent(MainActivity.this, RegisterActivity.class);
            startActivity(i);
        } else {
            Intent i = new Intent(this, ProfileActivity.class);
            startActivity(i);
        }

        break;

    case 14:
        Intent i = new Intent(this, LoginActivity.class);
        this.startActivity(i);
        break;

    default:
        break;
    }

    // update selected item and title, then close the drawer
    mDrawerList.setItemChecked(position, true);
    mDrawerList.setSelection(position);
    // setTitle(navMenuTitles[position]);
    mDrawerLayout.closeDrawer(mPanelMenu);

    if (currFragment != null && fragment != null) {
        boolean result = fragment.getClass()
                .equals(currFragment.getClass());
        if (result)
            return;
    }

    if (fragment != null) {

        if (fragment instanceof MapFragment) {
            currFragment = fragment;
            Handler h = new Handler();
            h.postDelayed(new Runnable() {

                @Override
                public void run() {
                    // TODO Auto-generated method stub

                    FragmentManager fragmentManager = MainActivity.this
                            .getSupportFragmentManager();
                    fragmentManager.beginTransaction()
                            .replace(R.id.frame_container, currFragment)
                            .commit();
                }
            }, Config.DELAY_SHOW_ANIMATION + 200);
        } else {

            currFragment = fragment;
            FragmentManager fragmentManager = this
                    .getSupportFragmentManager();
            fragmentManager.beginTransaction()
                    .replace(R.id.frame_container, fragment).commit();
        }

    }
}

@Override
public void setTitle(CharSequence title) {
    mTitle = title;
    getActionBar().setTitle(mTitle);
}

/**
 * When using the ActionBarDrawerToggle, you must call it during
 * onPostCreate() and onConfigurationChanged()...
 */
@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    // Sync the toggle state after onRestoreInstanceState has occurred.
    mDrawerToggle.syncState();
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    // Pass any configuration change to the drawer toggls
    mDrawerToggle.onConfigurationChanged(newConfig);

}

public void updateMenuList() {

    UserAccessSession accessSession = UserAccessSession.getInstance(this);
    UserSession userSession = accessSession.getUserSession();

    if (userSession == null) {
        MENUS = UIConfig.MENUS_NOT_LOGGED;
    } else {
        MENUS = UIConfig.MENUS_LOGGED;
    }

    showList();
}

public void showList() {

    MGListAdapter adapter = new MGListAdapter(this, MENUS.length,
            R.layout.menu_entry);

    adapter.setOnMGListAdapterAdapterListener(new OnMGListAdapterAdapterListener() {

        @Override
        public void OnMGListAdapterAdapterCreated(MGListAdapter adapter,
                View v, int position, ViewGroup viewGroup) {
            // TODO Auto-generated method stub

            FrameLayout frameCategory = (FrameLayout) v
                    .findViewById(R.id.frameCategory);
            View frameHeader = v.findViewById(R.id.frameHeader);

            frameCategory.setVisibility(View.GONE);
            frameHeader.setVisibility(View.GONE);

            Menu menu = MENUS[position];

            if (menu.getHeaderType() == HeaderType.HeaderType_CATEGORY) {
                frameCategory.setVisibility(View.VISIBLE);
                Spanned title = Html.fromHtml(MainActivity.this
                        .getResources().getString(menu.getMenuResTitle()));
                TextView tvTitle = (TextView) v.findViewById(R.id.tvTitle);
                tvTitle.setText(title);

                ImageView imgViewIcon = (ImageView) v
                        .findViewById(R.id.imgViewIcon);
                imgViewIcon.setImageResource(menu.getMenuResIconSelected());
            } else {
                frameHeader.setVisibility(View.VISIBLE);

                Spanned title = Html.fromHtml(MainActivity.this
                        .getResources().getString(menu.getMenuResTitle()));
                TextView tvTitleHeader = (TextView) v
                        .findViewById(R.id.tvTitleHeader);
                tvTitleHeader.setText(title);
            }
        }
    });
    mDrawerList.setAdapter(adapter);
    adapter.notifyDataSetChanged();
}

以下是适配器代码

public class MGListAdapter extends BaseAdapter  {

Context c;
private int count;
private int resId;
OnMGListAdapterAdapterListener mCallback;

@SuppressWarnings("unused")
private int mLastPosition = 1;

public interface OnMGListAdapterAdapterListener {

    public void OnMGListAdapterAdapterCreated(MGListAdapter 
            adapter, View v, int position, ViewGroup viewGroup);
}

public void setOnMGListAdapterAdapterListener(OnMGListAdapterAdapterListener listener) {

    try {
        mCallback = (OnMGListAdapterAdapterListener) listener;
    } catch (ClassCastException e)  {
        throw new ClassCastException(this.toString() + " must implement OnMGListAdapterAdapterListener");
    }
}


public MGListAdapter(Context c, int count, int resId) {
    this.c = c;
    this.count = count;
    this.resId = resId;
}

@Override
public int getCount() {
    // TODO Auto-generated method stub
    return count;
}

@Override
public Object getItem(int pos) {
    // TODO Auto-generated method stub
    return null;
}

@Override
public long getItemId(int pos) {
    // TODO Auto-generated method stub
    return pos;
}

@Override
public View getView(int pos, View v, ViewGroup viewGroup) {
    // TODO Auto-generated method stub

    ViewHolder viewHolder = null;

    if(v == null) {
        LayoutInflater li = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = li.inflate(resId, null);

        viewHolder = new ViewHolder();
        viewHolder.view = v;
        v.setTag(viewHolder);
    }
    else {
        viewHolder = (ViewHolder) v.getTag();
        Log.w("MGListAdapter Class", "View being reused.");
    }

    if(mCallback != null)
        mCallback.OnMGListAdapterAdapterCreated(this, viewHolder.view, pos, viewGroup);



    return v;
}

public class ViewHolder {

    public View view;
}

}

1 个答案:

答案 0 :(得分:2)

好的伙计们,我发现了我的错误,这是我身边的一个非常愚蠢的错误...... 在drawable文件夹中,我忘了调整菜单图标的大小,它是500px,现在我已经调整了所有图标,抽屉菜单再次正常,没有警告信息。

感谢@Sheychan,@ Gaurav和@nmio的努力。