androidjsonbackground-taskjsonparserasynctaskloader

Json Data reload again on configuration changes in background tasks


I have made an app Earthquake Report app. in that I am fetching earthquake data through an API and showing it in recycler view. This process runs on the background thread by using the Executor service method and runnable. But when I run my app and when I rotated my phone the background process is re-executed and reloads data . How to prevent it? I am using Java for making app.

RecyclerView recyclerView;
LinearLayout nointernetLinearLayout;

ArrayList<EarthquakeModel> earthquake;
private ImageView mEmptyView;
private Button mNoInternetButton;
boolean isConnected;
private static final String url = "https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=2021-09-10&endtime=2021-09-11";

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


    
    recyclerView = findViewById(R.id.recycler_view);
    nointernetLinearLayout = findViewById(R.id.no_internet);
    mEmptyView = findViewById(R.id.empty_view);
    earthquake = new ArrayList<>();





    ExecutorService service = Executors.newSingleThreadExecutor();
    service.execute(new Runnable() {


        @Override
        public void run() {



      
            QueryUtils queryUtils = new QueryUtils();
            String json = queryUtils.call(url);
            try {
                ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
                NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
                isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting();

                if (isConnected){
                    Log.i("This is background task","it is restarted if showing again");
                    JSONObject jsonObject = new JSONObject(json);
                    JSONArray jsonArray = jsonObject.getJSONArray("features");
                    for (int i=0; i<jsonArray.length(); i++){
                        JSONObject c = jsonArray.getJSONObject(i);
                        JSONObject properties = c.getJSONObject("properties");
                        double magnitude = properties.getDouble("mag");
                        String location = properties.getString("place");
                        long time = properties.getLong("time");
                        String url = properties.getString("url");
                        EarthquakeModel earthquakeModel = new EarthquakeModel(location, magnitude,time,url);
                        earthquake.add(earthquakeModel);
                    }
                }

            }catch (JSONException e){
                Log.e("Error","is"+e.getMessage());
            }

            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    View loadingIndicator = findViewById(R.id.loading_indicator);
                    loadingIndicator.setVisibility(View.GONE);
                    if (isConnected&&!earthquake.isEmpty()){
                        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getApplicationContext());
                        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
                        recyclerView.setLayoutManager(linearLayoutManager);
                        EarthquakeAdapter earthquakeAdapter = new EarthquakeAdapter(earthquake,MainActivity.this);
                        recyclerView.setAdapter(earthquakeAdapter);
                    }if(isConnected&&earthquake.isEmpty()){
                        recyclerView.setVisibility(View.GONE);
                        mEmptyView.setVisibility(View.VISIBLE);
                    }
                    if (!isConnected){
                        recyclerView.setVisibility(View.GONE);
                        nointernetLinearLayout.setVisibility(View.VISIBLE);
                    

                }
            });



        }
    });

}

Solution

  • Run the service in your viewModel, since the viewmodel survives the configuration change.

    The update the UI with LiveData.

    public ExampleViewModel extends ViewModel {
        
        private MutableLiveData<ArrayList<EarthquakeModel>> earthquake;
    
        public ExampleViewModel() {
            ExecutorService service = Executors.newSingleThreadExecutor();
            service.execute(new Runnable() {
                //get data
                earthquake.post(someData)
            }
        }
        public LiveData<ArrayList<EarthquakeModel>> getEarthQuake() {
            return earthquake;
        }
    }
    

    Then in your Activity observe the LiveData

    public class ExampleActivity extends Activity {
    
         private ExampleViewModel exampleViewModel;
    
         @Override
         protected void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             setContentView(R.layout.activity_main);
            exampleViewModel = new ViewModelProvider(this).get(ExampleViewModel.class);
            exampleViewModel.getEarthQuake().observe(getViewLifecycleOwner(), array -> {
              //do somthing with array
              }
         }
    }