检测应用程序是否从另一个活动返回MainActivity

时间:2019-01-13 17:52:07

标签: java android android-fragments android-activity

场景:

  • 我的应用程序通过以下方式的OnStart()方法刷新其内容: 通过从互联网下载一些东西来维护MainActivity。我用 OnStart(),因为我希望每当 用户打开应用程序,而不仅仅是打开OnCreate()
  • 该应用程序具有TabLayout,并且不同选项卡的内容被称为ViewPager中的片段
  • 这些片段包含自定义ListViews。单击列表项将调用一个新活动,该活动显示有关给定的更多信息 项目。使用片段从片段中调用OnClickListener 以下代码:

myListView.setOnItemClickListener(
        new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Intent myNewIntent = new Intent(parent.getContext(), activity_details.class);
                startActivity(myNewIntent);
            }
        });

我遇到的问题是,当用户通过按手机的后退按钮从这个新打开的活动中返回时,我的应用返回了MainActivity,OnStart()方法再次被执行,因此该应用下载了东西再次从互联网上删除,这是不希望的。 (仅当用户打开应用程序时,我才需要刷新)

这意味着我需要某种机制来发出信号,表明我们正在从另一个Activity返回。我有几个主意:

  1. 使用共享首选项。
  2. 使用某种全局变量(不是这个想法的好朋友)
  3. 数据库(嗯……我不这么认为)
  4. 在MainActivity中使用onActivityResult。乍一看听起来不错,但是当我从片段中调用新活动时,它将实际的活动调用与处理结果的地方分开,因此使代码复杂化

帮我分享您的想法。

4 个答案:

答案 0 :(得分:1)

您为什么不使用界面,并覆盖onBackPressed,以便它通过界面向MainActivity发送“嘿,我正在返回,所以不要下载任何内容”

片段

public class itemFragment extends Fragment {

    private OnFragmentInteractionListener mListener;

    public itemFragment() {
        // Required empty public constructor
    }


    public static itemFragment newInstance() {
        return new itemFragment();
    }

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

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_item, container, false);
    }

    // TODO: Rename method, update argument and hook method into UI event


    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        //send true to Main Activity before detaching
        mListener.onFragmentInteraction(true);
        mListener = null;
    }


    public interface OnFragmentInteractionListener {

        void onFragmentInteraction(Boolean iamBack);
    }
}

MainActivity

public class MainActivity extends AppCompatActivity implements itemFragment.OnFragmentInteractionListener {
    boolean backPress = false;

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

    @Override
    protected void onStart() {
        super.onStart();
        //Download whatever you want if backPress is false
        if (!backPress) {

        }
    }

    @Override
    public void onFragmentInteraction(Boolean backPress) {
        this.backPress = backPress;
    }
}

注意:我仍然没有尝试过,因此请告诉我您是否遇到任何问题。

答案 1 :(得分:1)

我认为使用SharedPreferences将是一个很好的解决方案。您可以在不想触发同步代码的活动中的onBackPressed()方法中设置一个值,然后在MainActivity的onStart()方法中检查它,如果它可以重置该值表示您正在从不想进行同步的状态返回。您可能还会发现其他状态(可能是配置更改),它们也不想在返回时同步,并使用相同的设置。

答案 2 :(得分:0)

读取detecting return from another activity,提示startActivityForResult();在调度事件时,这不会使任何事情复杂化,因此Fragment将得到通知:

MainActivity

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    this.currentFragment.onActivityResult(requestCode, resultCode, data);
}

当然,当前的Fragment也需要实现onActivityResult()

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    ...
}

然后可以从DetailActivity返回数据:

Intent data = new Intent();
this.setResult(AppCompatActivity.RESULT_OK, data);
this.finish();

答案 3 :(得分:0)

最简单的解决方案是活动变量。即使您不喜欢这种解决方案。我不知道您的体系结构是什么,但是使用viewModel完全可以了。即使没有它,它也是可以理解且易于维护的。

赞:

private var syncToPerformed: Boolean = true

override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
    if (keyCode == KeyEvent.KEYCODE_HOME) {
        syncToPerformed = true
    }
    return super.onKeyDown(keyCode, event)
}

override fun onCreate() {
    if (syncToPerformed) {
        // DO YOUR SYNCHRONISATION
       syncToPerformed = false
    }
}

在此解决方案中使用onStart也没有用。