以下代码中可能导致内存泄漏或崩溃的原因是什么?

时间:2013-08-15 20:24:24

标签: android

onbackpressed按钮上的代码崩溃了。不经常发生,但它是一些空指针活动。代码如下:

public class MainActivity extends AbsBaseActivity implements OnBackStackChangedListener {
    public static final int REQUEST_CODE_LIST = 100;

    private boolean mIsNavigationOpen = false;

    private boolean mIsSearchBarActive;

    public boolean isNavigationOpen() {
        return mIsNavigationOpen;
    }

    @SuppressWarnings("deprecation")
    public void setNavigationOpen(final boolean isNavigationOpen) {
        this.mIsNavigationOpen = isNavigationOpen;
        final ImageButton mainButton = (ImageButton) findViewById(R.id.button_main);
        if(isNavigationOpen) {
            mainButton.setBackgroundResource(R.drawable.bg_helios_active);
        } else {
            mainButton.setBackgroundDrawable(null);
        }
    }

    private final BroadcastReceiver mMainActivityReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(final Context context, final Intent intent) {
            final String action = intent.getAction();

            if (BroadcastActions.LIST_DELETE_ACTION.equals(action)) {
                if (mActiveFragment instanceof ListsFragment || mActiveFragment instanceof ListDetailsFragment) {
                    final Bundle bundle = intent.getExtras();
                    final String toastMessage = bundle.getString(DeleteListOperation.TOAST);
                    final boolean isSuccess = bundle.getBoolean(DeleteListOperation.IS_SUCCESS);
                    final Toast toast = Toast.makeText(getApplicationContext(), toastMessage, Toast.LENGTH_SHORT);
                    toast.setGravity(Gravity.CENTER, 0, 0);
                    toast.show();
                    if (isSuccess) {
                        if (mActiveFragment instanceof ListsFragment) {
                            final ListsFragment fragment = (ListsFragment) mActiveFragment;
                            fragment.onUpdate();
                        }
                    }
                }
            }
        }
    };

    public static void newInstance(final Activity activity) {
        final Intent intent = new Intent(activity, MainActivity.class);
        activity.startActivity(intent);
    }

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);

        initiateMainActionBar();

        final FragmentManager supportFragmentManager = getSupportFragmentManager();
        supportFragmentManager.addOnBackStackChangedListener(this);


        if (savedInstanceState == null) {
            mActiveFragment = DashboardFragment.getInstanceWithTransition(supportFragmentManager);
            BangoHelper.onStartSession(this);

        } else {
            resetToDashboard(supportFragmentManager);
        }
        BangoHelper.eventDashboard();
    }

    private void resetToDashboard(final FragmentManager supportFragmentManager) {
        FragmentStackManager.getInstance().clearBackStack(supportFragmentManager);
        mActiveFragment = DashboardFragment.getInstanceWithNoTransition(supportFragmentManager);
    }

    private void initiateMainActionBar() {
        final ActionBar actionBar = getSupportActionBar();
        actionBar.setDisplayShowCustomEnabled(true);
        actionBar.setCustomView(R.layout.actionbar_main);
        setupOnClickListenerForSearchButton(this);
        setupOnClickListenerForMainButton();
        setupOnClickListenerForSearchCancelButton(this);
        setupOnClickListenerForSearchClearButton(this);
    }

    private void setupOnClickListenerForSearchCancelButton(final MainActivity activity) {
        final Button cancelButton = (Button) findViewById(R.id.button_search_cancel);
        cancelButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(final View v) {
                final View actionBarView = findViewById(R.id.action_bar_container);
                mIsSearchBarActive = MenuUtils.changeActionBar(activity, actionBarView);
            }
        });
    }

    private void setupOnClickListenerForSearchClearButton(final Activity activity) {
        final ImageButton cancelButton = (ImageButton) findViewById(R.id.clear_search_textbox);
        cancelButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(final View view) {
                MenuUtils.clearSearchBar(activity);
            }
        });
    }

    private void setupOnClickListenerForMainButton() {
        final ImageButton mainButton = (ImageButton) findViewById(R.id.button_main);
        mainButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(final View v) {
                toggleNavigationPanel();
            }
        });
    }

    private void setupOnClickListenerForSearchButton(final MainActivity activity) {
        final ImageButton searchButton = (ImageButton) findViewById(R.id.search_button);
        searchButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(final View v) {
                final View searchBarView = findViewById(R.id.search_bar_container);
                mIsSearchBarActive = MenuUtils.changeActionBar(activity, searchBarView);
                BangoHelper.eventSearch();
            }
        });
    }

    @Override
    public void manageActionBar() {
        setTitle(null);
        getSupportActionBar().setDisplayShowHomeEnabled(false);
    }

    @Override
    public boolean onMenuItemSelected(final int featureId, final MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                toggleNavigationPanel();
                break;

            default:
                break;
        }
        return super.onMenuItemSelected(featureId, item);
    }

    @Override
    protected void onResume() {
        final IntentFilter filter = new IntentFilter();
        filter.addAction(BroadcastActions.USER_PROFILE);
        filter.addAction(BroadcastActions.NEWS_IMAGE);
        filter.addAction(BroadcastActions.NEWS_HEADLINES);

        registerReceiver(mMainActivityReceiver, filter);
        BangoAgent.onResume();
        super.onResume();
    }

    @Override
    protected void onPause() {
        unregisterReceiver(mMainActivityReceiver);
        super.onPause();
        BangoAgent.onIdle();
        saveTextSize();
    }

    private void saveTextSize() {
        final ContentResolver resolver = Application.getAppContext().getContentResolver();
        final ContentValues contentValues = new ContentValues();
        contentValues.put(GenericColumns.TEXT_SIZE, SharedPreferencesManager.getInstance().getTextSize().ordinal());

        SqlArguments argument = SqlArgumentsFactory.generateUserProfileUpdateSqlArguments();
        String where = argument.getWhereClause();
        String[] whereArgs = argument.getWhereArgs();
        resolver.update(UserProfileContentProvider.USER_PROFILE_URI, contentValues, where, whereArgs);
    }

    public void pushNewsArticlePagerFragment(final int position, final String selectedCategoryCode, final boolean isMyNews) {
        NewsArticlePagerFragment.newInstance(getSupportFragmentManager(), position, selectedCategoryCode, isMyNews);
    }

    public void onDashboardClicked(final View view) {
        toggleNavigationPanel();

        if (isFragmentVisible(DashboardFragment.TAG_DASHBOARD_FRAGMENT)) {
            return;
        }

        final FragmentManager manager = getSupportFragmentManager();
        final FragmentTransaction transaction = manager.beginTransaction();
        transaction.setCustomAnimations(R.anim.slide_in_from_right, R.anim.slide_out_to_left);
        FragmentStackManager.getInstance().clearBackStack(getSupportFragmentManager());
        mActiveFragment = DashboardFragment.getInstance();
        transaction.hide(mActiveFragment);
        transaction.show(mActiveFragment);
        transaction.commitAllowingStateLoss();
        updateActionBarTitle();
    }

    public void onNewsClicked(final View view) {
        if(mIsNavigationOpen) {
            toggleNavigationPanel();
        }

        if (isFragmentVisible(NewsFragment.TAG_NEWS_FRAGMENT)) {
            return;
        }

        FragmentStackManager.getInstance().clearBackStack(getSupportFragmentManager());
        mActiveFragment = NewsFragment.newInstance(getSupportFragmentManager());
        updateActionBarTitle();
    }

    public void onMarketClicked(final View view) {
        if(mIsNavigationOpen) {
            toggleNavigationPanel();
        }

        if (isFragmentVisible(MarketsFragment.TAG_MARKETS_FRAGMENT)) {
            return;
        }

        FragmentStackManager.getInstance().clearBackStack(getSupportFragmentManager());
        mActiveFragment = MarketsFragment.newInstance(getSupportFragmentManager());
        updateActionBarTitle();
    }

    public void onListsClicked(final View view) {
        if(mIsNavigationOpen) {
            toggleNavigationPanel();
        }

        if (isFragmentVisible(ListsContainerFragment.TAG_LIST_CONTAINER_FRAGMENT)) {
            return;
        }

        FragmentStackManager.getInstance().clearBackStack(getSupportFragmentManager());
        mActiveFragment = ListsContainerFragment.newInstance(getSupportFragmentManager());
        updateActionBarTitle();
    }

    public void onBriefcaseClicked(final View view) {
        if(mIsNavigationOpen) {
            toggleNavigationPanel();
        }

        if (isFragmentVisible(BriefcaseFragment.TAG_BRIEFCASE_FRAGMENT)) {
            return;
        }

        FragmentStackManager.getInstance().clearBackStack(getSupportFragmentManager());
        mActiveFragment = BriefcaseFragment.newInstance(getSupportFragmentManager());
        updateActionBarTitle();
    }

    private void toggleNavigationPanel() {
        final FragmentStackManager manager = FragmentStackManager.getInstance();
        if (mIsNavigationOpen) {
            NavigationPanelFragment.removeInstance(getSupportFragmentManager());
            updateActionBarTitle();
            BangoHelper.eventMainNav();
        } else {
            final TextView title = (TextView) findViewById(R.id.main_title);
            title.setText(getString(R.string.title_applications));
            NavigationPanelFragment.newInstance(getSupportFragmentManager(), manager.getTopTitle());
        }

        setNavigationOpen(!mIsNavigationOpen);
    }

    public void updateActionBarTitle() {
        final String title = FragmentStackManager.getInstance().getTopTitle();
        final TextView titleView = (TextView) findViewById(R.id.main_title);
        titleView.setText(title);
    }

    private boolean isFragmentVisible(final String tag) {
        Fragment fragment = FragmentStackManager.getInstance().getTopFragment();
        return fragment != null && tag.equals(fragment.getTag());
    }

    // TODO: refactor as need (e.g. make an Arraylist)
    public interface BackPressListener<T extends Fragment> {
        public boolean backPressed(MainActivity fragmentActivity);
    }

    private BackPressListener<Fragment> backPressListener = null;
    public void setBackPressListener (final BackPressListener<Fragment> backPressListener) {
            this.backPressListener = backPressListener;
    }


    @Override
    public void onBackPressed() {
        BangoHelper.eventBack();
        if (backPressListener != null) {
            boolean b = false;
            // Making sure we trigger the backPressed event if the listener is the top fragment
            String bplTag = ((Fragment)backPressListener).getTag();
            Fragment topFragment = FragmentStackManager.getInstance().getTopFragment();
            if (topFragment != null) {
                String topFragemtnTag = topFragment.getTag();
                if (bplTag != null && topFragemtnTag != null && bplTag.equals(topFragemtnTag)) {
                    b = backPressListener.backPressed(this);
                }
            }
            if (b)
                return;
            backPressListener = null;

        }

        if (mIsSearchBarActive) {
            MenuUtils.hideSearchView(this);
            mIsSearchBarActive = false;
        } else if (mIsNavigationOpen) {
            toggleNavigationPanel();
        } else if (!FragmentStackManager.getInstance().popTopFragment()) {
            Intent setIntent = new Intent(Intent.ACTION_MAIN);
            setIntent.addCategory(Intent.CATEGORY_HOME);
            setIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(setIntent);
        } else {
            Fragment topFragment = FragmentStackManager.getInstance().getTopFragment();
            if (topFragment == null) {
                mActiveFragment = DashboardFragment.getInstance();
                ((DashboardFragment)mActiveFragment).refreshDashboard();
            } else if (topFragment instanceof AbsArticlePagerFragment) {
                ((AbsArticlePagerFragment) topFragment).forceUpdateTextSize();
            } else if (topFragment instanceof AbsBaseArticleFragment) {
                ((AbsBaseArticleFragment) topFragment).forceUpdateTextSize();
            }
        }

        updateActionBarTitle();
    }

    public void onDestroy()
    {
      if (this.isFinishing())
      {
        BangoHelper.onEndSession(this);
      }
       super.onDestroy();
    }

    public void setActiveFragment(final Fragment fragment) {
        mActiveFragment = fragment;
    }

    public void setIsSearchBarActive(final boolean isSearchBarActive){
        mIsSearchBarActive = isSearchBarActive;
    }

    @Override
    public void onBackStackChanged() {
        Log.d("BackStack", "=================================================");
        for (int i = 0; i < getSupportFragmentManager().getBackStackEntryCount(); i++) {
            final BackStackEntry bse = getSupportFragmentManager().getBackStackEntryAt(i);
            Log.d("BackStack", "Changed: " + bse.getName());
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_LIST) {
            if (resultCode == RESULT_OK) {
                Fragment fragment = FragmentStackManager.getInstance().getTopFragment();

                if (fragment == null) { // Implies DashboardFragment because dashboard was never added to backstack
                    DashboardFragment.getInstance().onUpdate();
                } else if (fragment instanceof ListsContainerFragment) {
                    ((ListsContainerFragment) fragment).onUpdate();
                } else if (fragment instanceof ListDetailsFragment) {
                    ((ListDetailsFragment) fragment).onUpdate();
                }
            }
        }
    }


    @Override
    public void refreshScreen() {
        Fragment fragment = FragmentStackManager.getInstance().getTopFragment();

        if (fragment == null) { // Implies DashboardFragment
            DashboardFragment.getInstance().refreshScreen();
        } else if (fragment instanceof ListsContainerFragment) {
            ((ListsContainerFragment) fragment).refreshScreen();
        } else if (fragment instanceof ListDetailsFragment) {
            ((ListDetailsFragment) fragment).refreshScreen();
        } else if (fragment instanceof MarketsFragment) {
            ((MarketsFragment) fragment).refreshScreen();
        }

    }
}

有任何线索吗?谢谢!

logcat的:

MainActivity.onBackPressed  
3    android.app.Activity.onKeyUp    Activity.java, line 2194
4    android.view.KeyEvent.dispatch  KeyEvent.java, line 2782
5    android.app.Activity.dispatchKeyEvent   Activity.java, line 2428
6    com.actionbarsherlock.app.SherlockFragmentActivity.dispatchKeyEvent    
7    com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent     PhoneWindow.java, line 2076
8    android.view.ViewRootImpl.deliverKeyEventPostIme    ViewRootImpl.java, line 4196
9    android.view.ViewRootImpl.handleImeFinishedEvent    ViewRootImpl.java, line 4125
10   android.view.ViewRootImpl$ViewRootHandler.handleMessage     ViewRootImpl.java, line 3173
11   android.os.Handler.dispatchMessage  Handler.java, line 99
12   android.os.Looper.loop  Looper.java, line 137
13   android.app.ActivityThread.main     ActivityThread.java, line 5328
14   java.lang.reflect.Method.invokeNative  
15   java.lang.reflect.Method.invoke     Method.java, line 511
16   com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run  ZygoteInit.java, line 1102
17   com.android.internal.os.ZygoteInit.main     ZygoteInit.java, line 869
18   dalvik.system.NativeStart.main

1 个答案:

答案 0 :(得分:2)

public void onDestroy()
{
  if (this.isFinishing())
  {
    BangoHelper.onEndSession(this);
  }
   super.onDestroy();
}

我想在这里你需要调用super.onDestroy();在if条件之前如下:

public void onDestroy()
{
  super.onDestroy();
  if (this.isFinishing())
  {
    BangoHelper.onEndSession(this);
  }
}

super.onDestroy()必须是onDestroy方法的第一次调用,如果你覆盖它。

P.S。我发现了与您类似的问题,但是这里有JakeWharton / ActionBarSherlock问题列表中的菜单键。它有一个NULL检查问题。