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