简体   繁体   English

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

[英]Detecting if app returns to MainActivity from another activity

Scenario: 场景:

  • my application refreshes its contents in the OnStart() method of the MainActivity by downloading some stuff from the internet. 我的应用程序通过从Internet下载一些内容来刷新MainActivity的OnStart()方法中的内容。 I use the OnStart() as I'd like the contents to be refreshed whenever the user opens the application, not just at the OnCreate() 我使用OnStart()是因为我希望用户每次打开应用程序时都刷新内容,而不仅仅是在OnCreate()
  • The application has a tablayout and the contents of the different tabs are called as fragments from a ViewPager 该应用程序具有TabLayout,并且不同选项卡的内容被称为ViewPager中的片段
  • The fragments contain custom ListViews. 这些片段包含自定义ListView。 Clicking to a listitem calls a new activity displaying more information about the given item. 单击列表项将调用一个新活动,该活动显示有关给定项目的更多信息。 The OnClickListener is called from the fragment with the following code: 使用以下代码从片段中调用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);
            }
        });

The problem I have is that when the user returns from this newly opened activity by pressing the back button of his phone then my app returns to the MainActivity, the OnStart() method is executed again, so the app download stuff again from the internet, which is undesired. 我的问题是,当用户通过按手机的后退按钮从此新打开的活动中返回时,我的应用程序返回到MainActivity,再次执行OnStart()方法,因此该应用程序又从互联网上下载了东西,这是不希望的。 (I need a refresh only when the user opens the app) (仅当用户打开应用程序时,我才需要刷新)

This means I need some sort of a mechanism to signal that we are returning from a different Activity. 这意味着我需要某种机制来发出信号,表明我们正在从另一个Activity返回。 I have couple ideas: 我有几个想法:

  1. Using sharedpreferences. 使用共享首选项。
  2. Using some sort of a global variable (not a big friend of this idea) 使用某种全局变量(不是这个想法的好朋友)
  3. Database (ehh... I dont think so) 数据库(嗯...我不这么认为)
  4. Using the onActivityResult in the MainActivity. 在MainActivity中使用onActivityResult This sounds ok for the first sight but as I call the new activity from a fragment it separates the actual activity call from where I process the results, therefore complicates the code 乍一看听起来不错,但是当我从片段中调用新活动时,它将实际的活动调用与处理结果的地方分开,因此使代码复杂化

Help me out with sharing your ideas. 帮助我分享您的想法。

Why don't you use an interface, and override onBackPressed so it sends to MainActivity that "hey i am returning , so don't download anything" via the interface 您为什么不使用界面,并覆盖onBackPressed以便它通过界面向MainActivity发送“嘿,我正在返回,所以不要下载任何内容”

fragment 分段

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;
    }
}

Note : I still didn't try it, so tell me if you face any problem. 注意:我仍然没有尝试过,因此请告诉我您是否遇到任何问题。

I think using SharedPreferences would be a good solution. 我认为使用SharedPreferences将是一个很好的解决方案。 You could set a value in the onBackPressed() method in the activity you don't want to trigger the sync code in and then check for it in the onStart() method of your MainActivity, and reset the value if it indicates you are returning from a state that you don't want to do a sync. 您可以在不想触发同步代码的活动中的onBackPressed()方法中设置一个值,然后在MainActivity的onStart()方法中检查它,如果指示您正在返回,则重置该值从您不想进行同步的状态开始。 You may find other states (maybe configuration changes) you would not want to sync on returning from as well and use the same setting. 您可能还会发现其他状态(可能是配置更改),它们也不想在返回时同步,并使用相同的设置。

it reads detecting return from another activity , which hints for startActivityForResult() ; 它读取detecting return from another activity ,这暗示了startActivityForResult() this does not complicate anything, while dispatching the event, so that the Fragment will get notified: 在调度事件时,这不会使任何事情复杂化,因此可以通知Fragment

for the MainActivity : 对于MainActivity

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

of course, the current Fragment also would need to implement onActivityResult() : 当然,当前的Fragment也需要实现onActivityResult()

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

then one can return data from the DetailActivity : 然后可以从DetailActivity返回数据:

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

The easiest solution is an activity variable. 最简单的解决方案是活动变量。 Even if you don't like this kind of solution. 即使您不喜欢这种解决方案。 I don't know what is your architecture but with viewModel it's totally clean. 我不知道您的体系结构是什么,但是使用viewModel完全可以了。 Even without it, it's understandable and easy to maintain. 即使没有它,它也是可以理解且易于维护的。

Like this: 像这样:

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
    }
}

Also it's not useful to use onStart with this solution. 同样,在此解决方案中使用onStart也没有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM