【问题标题】:Empty intent (nullpointer exception) in master/detail flow when clicking "up" in actionbar单击操作栏中的“向上”时,主/详细信息流中的空意图(空指针异常)
【发布时间】:2014-03-11 21:38:54
【问题描述】:

这可能是一个有点长的帖子,所以我提前道歉。

我正在使用主/详细信息流来显示项目列表,单击它会打开详细信息视图。这些项目是从 Web 服务加载的。 它在带有碎片的平板电脑上运行良好,但在手机上却不断崩溃。它可以正确显示项目详细信息(CheatViewPageIndicator.java),但是当我使用操作栏左上角的“向上”按钮返回父活动(CheatListActivity.java)时,应用程序不断崩溃并出现空指针异常。我想我在错误的位置从 web 服务加载数据,这就是它崩溃的原因。我将在这里编写我的代码,希望有人能给我一个建议,我应该如何以正确的方式做到这一点。

(为了缩短文章的篇幅,我对课程进行了一些调整。)

“主”活动:

public class CheatListActivity extends FragmentActivity implements CheatListFragment.Callbacks, ReportCheatDialogListener, RateCheatDialogListener {

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

        settings = getSharedPreferences(Konstanten.PREFERENCES_FILE, 0);
        editor = settings.edit();

        cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); 

        cheatProgressDialog = ProgressDialog.show(this, getString(R.string.please_wait) + "...", getString(R.string.retrieving_data) + "...", true);

        handleIntent(getIntent());

        if (findViewById(R.id.cheat_detail_container) != null) {
            // The detail container view will be present only in the
            // large-screen layouts (res/values-large and
            // res/values-sw600dp). If this view is present, then the
            // activity should be in two-pane mode.
            mTwoPane = true;

            // In two-pane mode, list items should be given the
            // 'activated' state when touched.
            ((CheatListFragment) getSupportFragmentManager().findFragmentById(R.id.cheat_list)).setActivateOnItemClick(true);
        }
        cheatProgressDialog.dismiss();
        // TODO: If exposing deep links into your app, handle intents here.

    }

    private void handleIntent(final Intent intent) {

        new Thread(new Runnable() {

            @Override
            public void run() {
                gameObj = new Gson().fromJson(intent.getStringExtra("gameObj"), Game.class);

                runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        getActionBar().setDisplayHomeAsUpEnabled(true);
                        getActionBar().setTitle(gameObj.getGameName());
                        getActionBar().setSubtitle(gameObj.getSystemName());
                    }

                });
                try {
                    if (cm.getActiveNetworkInfo() != null) {
                        if (member == null) {
                            cheats = Webservice.getCheatList(gameObj, 0);
                        } else {
                            cheats = Webservice.getCheatList(gameObj, member.getMid());
                        }
                        cheatsArrayList = new ArrayList<Cheat>();

                        if (cheats != null) {
                            for (int j = 0; j < cheats.length; j++) {
                                cheatsArrayList.add(cheats[j]);
                            }
                        } else {
                            Log.e("CheatListActivity()", "Webservice.getCheatList() == null");
                        }

                        for (int i = 0; i < cheats.length; i++) {
                            Log.d("cheats", cheats[i].getCheatTitle());
                        }

                        gameObj.setCheats(cheats);

                        // Put game object to local storage for large games like
                        // Pokemon
                        editor.putString(Konstanten.PREFERENCES_TEMP_GAME_OBJECT_VIEW, new Gson().toJson(gameObj));
                        editor.commit();
                    } else {
                        Log.e("CheatTitleList:getCheats()", "No Network");
                        Toast.makeText(CheatListActivity.this, R.string.no_internet, Toast.LENGTH_SHORT).show();
                    }

                } catch (Exception ex) {
                    Log.e(getClass().getName(), "Error executing getCheats()", ex);
                }
            }
        }).start();

    }

    public Cheat[] getCheatsForFragment(final Intent intent) {

        gameObj = new Gson().fromJson(intent.getStringExtra("gameObj"), Game.class);

        runOnUiThread(new Runnable() {

            @Override
            public void run() {
                getActionBar().setDisplayHomeAsUpEnabled(true);
                getActionBar().setTitle(gameObj.getGameName());
                getActionBar().setSubtitle(gameObj.getSystemName());
            }

        });

        try {
            if (cm.getActiveNetworkInfo() != null) {
                if (member == null) {
                    cheats = Webservice.getCheatList(gameObj, 0);
                } else {
                    cheats = Webservice.getCheatList(gameObj, member.getMid());
                }
                cheatsArrayList = new ArrayList<Cheat>();

                if (cheats != null) {
                    for (int j = 0; j < cheats.length; j++) {
                        cheatsArrayList.add(cheats[j]);
                    }
                } else {
                    Log.e("CheatListActivity()", "Webservice.getCheatList() == null");
                }

                for (int i = 0; i < cheats.length; i++) {
                    Log.d("cheats", cheats[i].getCheatTitle());
                }

                gameObj.setCheats(cheats);

                // Put game object to local storage for large games like Pokemon
                editor.putString(Konstanten.PREFERENCES_TEMP_GAME_OBJECT_VIEW, new Gson().toJson(gameObj));
                editor.commit();
            } else {
                Log.e("CheatTitleList:getCheats()", "No Network");
                Toast.makeText(this, R.string.no_internet, Toast.LENGTH_SHORT).show();
            }

        } catch (Exception ex) {
            Log.e(getClass().getName(), "Error executing getCheats()", ex);
        }

        return cheats;
    }

    /**
     * Callback method from {@link CheatListFragment.Callbacks} indicating that
     * the item with the given ID was selected.
     */
    @Override
    public void onItemSelected(int id) {
        if (mTwoPane) {
            // In two-pane mode, show the detail view in this activity by
            // adding or replacing the detail fragment using a
            // fragment transaction.

            visibleCheat = cheats[id];

            cheatForumFragment = new CheatForumFragment();
            cheatDetailMetaFragment = new CheatDetailMetaFragment();

            // VIEW FOR TABLETS
            Bundle arguments = new Bundle();
            arguments.putInt(CheatDetailTabletFragment.ARG_ITEM_ID, id);
            arguments.putString("cheatObj", new Gson().toJson(cheats[id]));
            arguments.putString("cheatForumFragment", new Gson().toJson(cheatForumFragment));
            arguments.putString("cheatDetailMetaFragment", new Gson().toJson(cheatDetailMetaFragment));

            cheatDetailFragment = new CheatDetailTabletFragment();
            cheatDetailFragment.setArguments(arguments);
            getSupportFragmentManager().beginTransaction().replace(R.id.cheat_detail_container, cheatDetailFragment).commit();

        } else {
            // In single-pane mode, simply start the detail activity
            // for the selected item ID.
            // Intent detailIntent = new Intent(this, YyyDetailActivity.class);
            // detailIntent.putExtra(YyyDetailFragment.ARG_ITEM_ID, id);
            // startActivity(detailIntent);

            editor.putInt(Konstanten.PREFERENCES_PAGE_SELECTED, id);
            editor.commit();

            // Using local Preferences to pass data for large game objects
            // (instead of intent) such as Pokemon
            Intent explicitIntent = new Intent(CheatListActivity.this, CheatViewPageIndicator.class);
            explicitIntent.putExtra("selectedPage", id);
            explicitIntent.putExtra("layoutResourceId", R.layout.activity_cheatview_pager);
            explicitIntent.putExtra("pageIndicatorColor", Konstanten.CYAN_DARK);
            startActivity(explicitIntent);

        }
    }   
}

还有列表视图的片段。

public class CheatListFragment extends ListFragment {

    /**
     * The serialization (saved instance state) Bundle key representing the
     * activated item position. Only used on tablets.
     */
    private static final String STATE_ACTIVATED_POSITION = "activated_position";

    /**
     * The fragment's current callback object, which is notified of list item
     * clicks.
     */
    private Callbacks mCallbacks = sDummyCallbacks;

    /**
     * The current activated item position. Only used on tablets.
     */
    private int mActivatedPosition = ListView.INVALID_POSITION;

    /**
     * A callback interface that all activities containing this fragment must
     * implement. This mechanism allows activities to be notified of item
     * selections.
     */
    public interface Callbacks {
        /**
         * Callback for when an item has been selected.
         */
        public void onItemSelected(int position);
    }

    /**
     * A dummy implementation of the {@link Callbacks} interface that does
     * nothing. Used only when this fragment is not attached to an activity.
     */
    private static Callbacks sDummyCallbacks = new Callbacks() {
        @Override
        public void onItemSelected(int id) {
        }
    };


    /**
     * Mandatory empty constructor for the fragment manager to instantiate the
     * fragment (e.g. upon screen orientation changes).
     */
    public CheatListFragment() {
    }

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

        cheatListActivity = (CheatListActivity) getActivity();
        fontRoboto = Tools.getFontRobotoRegular(getActivity().getAssets());

        settings = cheatListActivity.getSharedPreferences(Konstanten.PREFERENCES_FILE, 0);

        gameObj = new Gson().fromJson(settings.getString(Konstanten.PREFERENCES_TEMP_GAME_OBJECT_VIEW, null), Game.class);

        if( gameObj == null) {
            new GetCheatsTask().execute(new Game());            
        } else {
            new GetCheatsTask().execute(gameObj);           
        }
    }

    private class GetCheatsTask extends AsyncTask<Game, Void, Void> {

        @Override
        protected Void doInBackground(Game... params) {

            if (params[0].getCheats() == null) {
                cheats = cheatListActivity.getCheatsForFragment(cheatListActivity.getIntent()); 
            } else {
                cheats = params[0].getCheats();
            }

            for (int i = 0; i < cheats.length; i++) {
                Log.d("Cheat Item ", cheats[i].getCheatTitle());
                cheatsArrayList.add(cheats[i]);
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);

            cheatAdapter = new CheatAdapter(getActivity(), R.layout.cheatlist_item, cheatsArrayList);
            setListAdapter(cheatAdapter);
        }
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        // Restore the previously serialized activated item position.
        if (savedInstanceState != null && savedInstanceState.containsKey(STATE_ACTIVATED_POSITION)) {
            setActivatedPosition(savedInstanceState.getInt(STATE_ACTIVATED_POSITION));
        }
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        // Activities containing this fragment must implement its callbacks.
        if (!(activity instanceof Callbacks)) {
            throw new IllegalStateException("Activity must implement fragment's callbacks.");
        }

        mCallbacks = (Callbacks) activity;
    }

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

        // Reset the active callbacks interface to the dummy implementation.
        mCallbacks = sDummyCallbacks;
    }

    @Override
    public void onListItemClick(ListView listView, View view, int position, long id) {
        super.onListItemClick(listView, view, position, id);

        // Notify the active callbacks interface (the activity, if the
        // fragment is attached to one) that an item has been selected.
        // mCallbacks.onItemSelected(DummyContent.ITEMS.get(position).id);
        mCallbacks.onItemSelected(position);
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        if (mActivatedPosition != ListView.INVALID_POSITION) {
            // Serialize and persist the activated item position.
            outState.putInt(STATE_ACTIVATED_POSITION, mActivatedPosition);
        }
    }

    /**
     * Turns on activate-on-click mode. When this mode is on, list items will be
     * given the 'activated' state when touched.
     */
    public void setActivateOnItemClick(boolean activateOnItemClick) {
        // When setting CHOICE_MODE_SINGLE, ListView will automatically
        // give items the 'activated' state when touched.
        getListView().setChoiceMode(activateOnItemClick ? ListView.CHOICE_MODE_SINGLE : ListView.CHOICE_MODE_NONE);
    }

    private void setActivatedPosition(int position) {
        if (position == ListView.INVALID_POSITION) {
            getListView().setItemChecked(mActivatedPosition, false);
        } else {
            getListView().setItemChecked(position, true);
        }

        mActivatedPosition = position;
    }

    private class CheatAdapter extends ArrayAdapter<Cheat> {

        private final ArrayList<Cheat> items;

        public CheatAdapter(Context context, int textViewResourceId, ArrayList<Cheat> items) {
            super(context, textViewResourceId, items);
            this.items = items;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View v = convertView;
            if (v == null) {
                LayoutInflater vi = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                v = vi.inflate(R.layout.cheatlist_item, null);
            }

            try {
                Cheat cheat = items.get(position);
                if (cheat != null) {

                    TextView tt = (TextView) v.findViewById(R.id.game_title);
                    tt.setText(cheat.getCheatTitle());
                    tt.setTypeface(fontRoboto);

                    // Durchschnittsrating (nicht Member-Rating)
                    RatingBar ratingBar = (RatingBar) v.findViewById(R.id.small_ratingbar);
                    ratingBar.setNumStars(5);
                    ratingBar.setRating(cheat.getRatingAverage() / 2);

                    ImageView flag_newaddition = (ImageView) v.findViewById(R.id.newaddition);
                    if (cheat.getDayAge() < Konstanten.CHEAT_DAY_AGE_SHOW_NEWADDITION_ICON) {
                        flag_newaddition.setImageResource(R.drawable.flag_new);
                        flag_newaddition.setVisibility(View.VISIBLE);
                    } else {
                        flag_newaddition.setVisibility(View.GONE);
                    }

                    ImageView flag_screenshots = (ImageView) v.findViewById(R.id.screenshots);
                    if (cheat.isScreenshots()) {
                        flag_screenshots.setVisibility(View.VISIBLE);
                        flag_screenshots.setImageResource(R.drawable.flag_img);
                    } else {
                        flag_screenshots.setVisibility(View.GONE);
                    }

                    ImageView flag_german = (ImageView) v.findViewById(R.id.flag);
                    if (cheat.getLanguageId() == 2) { // 2 = Deutsch
                        flag_german.setVisibility(View.VISIBLE);
                        flag_german.setImageResource(R.drawable.flag_german);
                    } else {
                        flag_german.setVisibility(View.GONE);
                    }

                }
            } catch (Exception e) {
                Log.e(getClass().getName() + ".getView ERROR:", e.getMessage());
            }
            return v;
        }
    }
}

双窗格模式下的详细视图(在平板电脑上):

public class CheatDetailTabletFragment extends Fragment implements OnClickListener {
    /**
     * The fragment argument representing the item ID that this fragment
     * represents.
     */
    public static final String ARG_ITEM_ID = "item_id";

    /**
     * The dummy content this fragment is presenting.
     */
    private CheatContent.CheatItem mItem;
    private View rootView;

    /**
     * Mandatory empty constructor for the fragment manager to instantiate the
     * fragment (e.g. upon screen orientation changes).
     */
    public CheatDetailTabletFragment() {
    }

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

        ca = (CheatListActivity) getActivity();

        cheatTitleTypeface = Tools.getFontRobotoThin(getActivity().getAssets());
        cheatTextTypeface = Tools.getFontRobotoRegular(getActivity().getAssets());

        settings = getActivity().getSharedPreferences(Konstanten.PREFERENCES_FILE, 0);
        editor = settings.edit();

        if (getArguments().containsKey(ARG_ITEM_ID)) {
            // Load the dummy content specified by the fragment
            // arguments. In a real-world scenario, use a Loader
            // to load content from a content provider.

            mItem = CheatContent.ITEM_MAP.get(getArguments().getInt(ARG_ITEM_ID));
            cheatObj = new Gson().fromJson(getArguments().getString("cheatObj"), Cheat.class);

            cheatForumFragment = new Gson().fromJson(getArguments().getString("cheatForumFragment"), CheatForumFragment.class);
            cheatDetailMetaFragment = new Gson().fromJson(getArguments().getString("cheatDetailMetaFragment"), CheatDetailMetaFragment.class);
        }

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        rootView = inflater.inflate(R.layout.fragment_cheat_detail, container, false);

        // ...

        // Show the dummy content as text in a TextView.
        if (mItem != null) {
            ((TextView) rootView.findViewById(R.id.text_cheat_before_table)).setText(mItem.getCheatTitle());
            ((TextView) rootView.findViewById(R.id.text_cheat_title)).setText(mItem.getCheatId());
        }

        // ...

        populateView();         

        return rootView;
    }

    /**
     * Create Layout
     */
    private void populateView() {
        // fills the view. no problems here.
    }

    /**
     * Populate Table Layout
     */
    private void fillTableContent() {
        // filling table content here. no problems here.
    }

    private void fillSimpleContent() {
        // filling with other content. works fine, too.
    }

}

单窗格模式下的详细视图(在手机上):

public class CheatViewPageIndicator extends FragmentActivity implements ReportCheatDialogListener, RateCheatDialogListener {

    // define variables...

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        LayoutInflater inflater = LayoutInflater.from(this);
        intent = getIntent();

        viewLayout = inflater.inflate(intent.getIntExtra("layoutResourceId", R.layout.activity_cheatview_pager), null);
        setContentView(viewLayout);

        settings = getSharedPreferences(Konstanten.PREFERENCES_FILE, 0);
        editor = settings.edit();

        getActionBar().setHomeButtonEnabled(true);
        getActionBar().setDisplayHomeAsUpEnabled(true);

        try {
            gameObj = new Gson().fromJson(settings.getString(Konstanten.PREFERENCES_TEMP_GAME_OBJECT_VIEW, null), Game.class);
            if (gameObj == null) {
                gameObj = new Gson().fromJson(intent.getStringExtra("gameObj"), Game.class);
            }
            editor.putString(Konstanten.PREFERENCES_TEMP_GAME_OBJECT_VIEW, new Gson().toJson(gameObj));
            editor.commit();

            pageSelected = intent.getIntExtra("selectedPage", 0);
            activePage = pageSelected;
            pageIndicatorColor = intent.getIntExtra("pageIndicatorColor", Konstanten.CYAN_DARK);
            cheatObj = gameObj.getCheats();
            visibleCheat = cheatObj[pageSelected];

            getActionBar().setTitle(gameObj.getGameName());
            getActionBar().setSubtitle(gameObj.getSystemName());

            initialisePaging();
        } catch (Exception e) {
            Log.e(CheatViewPageIndicator.class.getName(), e.getMessage() + "");
        }

    }

    private void initialisePaging() {
        // ...
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.handset_cheatview_menu, menu);

        // Search
        getMenuInflater().inflate(R.menu.search_menu, menu);

        // Associate searchable configuration with the SearchView
        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
        searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));

        return super.onCreateOptionsMenu(menu);
    }



    @Override
    protected void onResume() {
        super.onResume();
        invalidateOptionsMenu();
    }

    public ConnectivityManager getConnectivityManager() {
        if (cm == null) {
            cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        }
        return cm;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case android.R.id.home:
            // This ID represents the Home or Up button. In the case of this
            // activity, the Up button is shown. Use NavUtils to allow users
            // to navigate up one level in the application structure. For
            // more details, see the Navigation pattern on Android Design:
            //
            // http://developer.android.com/design/patterns/navigation.html#up-vs-back

            // onBackPressed();
            // return true;

            Intent upIntent = new Intent(this, CheatListActivity.class);
            NavUtils.getParentActivityIntent(this);
            if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
                // This activity is NOT part of this app's task, so create a new
                // task when navigating up, with a synthesized back stack.
                TaskStackBuilder.create(this)
                // Add all of this activity's parents to the back stack
                        .addNextIntentWithParentStack(upIntent)
                        // Navigate up to the closest parent
                        .startActivities();
            } else {
                // This activity is part of this app's task, so simply
                // navigate up to the logical parent activity.
                // NavUtils.navigateUpTo(this, upIntent);
                upIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(upIntent);
                finish();
            }
            return true;
        }
        return super.onOptionsItemSelected(item);

    }       

}   

因此,在单窗格模式下(在手机上),当我从 CheatViewPageIndicator.java 单击操作栏中的“向上”按钮以获取 CheatListActivity.java 时,我得到一个指向此行的空指针异常:

gameObj = new Gson().fromJson(intent.getStringExtra("gameObj"), Game.class);    

返回时似乎“意图”为空。我想知道为什么会这样?我需要做什么才能将数据保留在意图中? (或任何其他解决方案如何摆脱空指针对我来说也很好)。我有点绝望,我一直在寻找解决方案太久了。

非常感谢您的帮助。

【问题讨论】:

  • “似乎意图是空的”您是否调试并验证了这一点,还是您只是在猜测?
  • 我已经对其进行了调试,并且那里出现了空指针异常。单击操作栏中的“向上”按钮时,我无法弄清楚为什么它为空。如果我单击硬件后退按钮,我不会收到空指针异常。
  • 请发布异常的堆栈跟踪。它可能包含一些提示。
  • 在 CheatViewPageIndicator 中单击“向上”时的日志文件(对不起,评论的最大长度真的很短) 03-14 22:48:28.663: E/AndroidRuntime(31372): 引起: java.lang .NullPointerException 03-14 22:48:28.663: E/AndroidRuntime(31372): 在 com.cheatdatabase.CheatListActivity.getCheatsForFragment(CheatListActivity.java:191) 03-14 22:48:28.663: E/AndroidRuntime(31372): 在com.cheatdatabase.CheatListFragment$GetCheatsTask.doInBackground(CheatListFragment.java:127) 03-14 22:48:28.663: E/AndroidRuntime(31372): at com.cheatdatabase.CheatListFragment$GetCheatsTask.doInBackground(CheatListFragment.java:1)
  • 您是否在清单中指定 CheatListActivity.java 作为 CheatViewPageIndicator.java 的父活动?

标签: android android-intent android-fragments master-detail


【解决方案1】:

我通常使用另一种指定父活动的方式,它在清单文件中包含一个属性。

在CheatViewPageIndicator.java的activity标签中,添加这个属性:

 <activity
        ...
        android:parentActivityName="your.app.package.CheatListActivity" >
 </activity>   

并注释掉您为 upIntent 编写的所有行。这应该可以解决问题。

【讨论】:

  • 将该行添加到清单中并删除了 upIntent 行。单击时向上按钮仍然有效,但我仍然得到一个空指针。 16:57:java.lang.RuntimeException:执行 doInBackground() 时发生错误 16:57:原因:java.lang.NullPointerException 16:57:在 .CheatListActivity.getCheatsForFragment(CheatListActivity.java:196) 16:57:在 .CheatListFragment$GetCheatsTask.doInBackground(CheatListFragment.java:127) 16:57: 在 .CheatListFragment$GetCheatsTask.doInBackground(CheatListFragment.java:1) 16:57: 在 android.os.AsyncTask$2.call(AsyncTask.java:第288章)
  • 你能告诉我哪几行是 CheatListActivity.java:196,127 和 1 吗?
  • 代码行有:CheatListActivity.java 196: Tools.initGA(CheatListActivity.this, tracker, SCREEN_LABEL, "Cheat List", gameObj.getGameName());和 CheatListFragment.java 127:cheats = cheatListActivity.getCheatsForFragment(cheatListActivity.getIntent());和CheatListFragment.java 1:包com.cheatdatabase;到目前为止,我发现当我在子项中单击“向上”时,父项中的“意图”为空。为什么会这样我不知道。如何保存保存在父母“意图”中的数据?
【解决方案2】:

我几乎可以肯定问题来自CheatViewPageIndicator 中的onOptionsItemSelected()。你不需要在那里开始一个新的活动,在主从模式中,一次总是有一个相同的活动。只有片段在变化。

要提供正确使用“向上”按钮的能力,您只需在添加片段时调用fragmentTransaction.addToBackStack(null)。 Android 将自行处理所有堆栈逻辑。在android.R.id.home 的情况下根本不要做任何事情,你不需要它。

【讨论】:

  • 好的,我已经添加了 fragmentTransaction.addToBackStack(null) 但我认为这不会有任何区别。但我遇到的问题只是在单窗格模式下,我实际上是在开始一项新活动,而不仅仅是替换片段。在平板电脑上它可以正常工作(双窗格模式)。 “向上”的问题只在手机应用使用单窗格模式时出现。
  • 我明白这一点,我建议您从电话片段中删除 onOptionsItemSelected() 方法,以及 addToBackStack() 呼叫。
  • 我已经从 CheatViewPageIndicator.java 的 onOptionsItemSelected() 中删除了那个(“case android.R.id.home”)。 “向上”功能仍然有效,但空指针问题仍然存在。
  • NPE 和以前在同一个地方?后退按钮点击仍然有效?
  • 对不起,我错过了一件重要的事情:你的手机细节视图是活动,如果你实现片段而不是它会更容易使用,它会更适合主细节模式。如果您想将其保留为活动,请不要在CheatListActivityonCreate() 中执行第二次加载。从第二个活动返回后,它应该处于一致状态。
【解决方案3】:

我遇到了这个问题,并通过在 Nav 之前将 Intent Extras 放入 upIntent 中来解决它,这样它们就会被传递给父 List 活动。

public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case android.R.id.home:
            ...
            Intent upIntent = new Intent(this, CheatListActivity.class);
-->         upIntent.putExtras(getIntent().getExtras());
            NavUtils.getParentActivityIntent(this);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-03
    • 2013-04-10
    • 1970-01-01
    • 2013-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多