I am just trying to fetch list of earthquakes and making an array list out of it. To avoid multiple API calls on screen rotation, I implemented Mutable Live Data class with ViewModel but by logging in the QueryUtils class where I make the network request, I found out that even when I rotate the device, network request is still being made. I don't understand why. Here are my relevant classes:
public class EarthquakeActivity extends AppCompatActivity {
private static final String LOG_TAG = "MainActivity";
private MyModel mMyModel;
private ViewModelProvider mViewModelProvider;
private RecyclerView mRecyclerView;
private TextView mEmptyView;
private EarthquakeAdapter mEarthquakeAdapter;
private ProgressBar mProgressBar;
private ConnectivityManager mConnectivityManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.earthquake_activity);
mEmptyView = findViewById(R.id.empty_view);
// get the progress bar to indicate loading
mProgressBar = findViewById(R.id.loading_bar);
// set a view model provider for the current activity
mViewModelProvider = new ViewModelProvider(this);
// get the view model for the class
mMyModel = mViewModelProvider.get(MyModel.class);
// find a reference to the {@link RecyclerView} in the layout
mRecyclerView = findViewById(R.id.earthquakes);
mConnectivityManager = getSystemService(ConnectivityManager.class);
mEmptyView.setText("No internet available");
mEmptyView.setVisibility(View.VISIBLE);
Handler handler = new Handler(Looper.getMainLooper());
mConnectivityManager.registerDefaultNetworkCallback(new ConnectivityManager.NetworkCallback(){
@Override
public void onAvailable(Network network) {
handler.post(new Runnable() {
@Override
public void run() {
mEmptyView.setVisibility(View.GONE);
mProgressBar.setVisibility(View.VISIBLE);
fetchData();
}
});
}
});
Log.e(LOG_TAG,"Visibility changed");
}
private void fetchData(){
// fetch the list of earthquakes
mMyModel.getEarthquakes().observe(EarthquakeActivity.this, new Observer<ArrayList<Earthquake>>() {
@Override
public void onChanged(ArrayList<Earthquake> earthquakes) {
Log.v(LOG_TAG,"fetching the data");
// set up recycler view with this data, this will work even if you rotate the device
setUpRecyclerView(earthquakes);
}
});
}
private void setUpRecyclerView(ArrayList<Earthquake> earthquakes) {
if(earthquakes == null || earthquakes.size() == 0) {
mRecyclerView.setVisibility(View.GONE);
mProgressBar.setVisibility(View.GONE);
mEmptyView.setText(R.string.no_data_available);
mEmptyView.setVisibility(View.VISIBLE);
}
else {
mRecyclerView.setVisibility(View.VISIBLE);
mEmptyView.setVisibility(View.GONE);
mProgressBar.setVisibility(View.GONE);
// create adapter passing in the earthquake data
mEarthquakeAdapter = new EarthquakeAdapter(EarthquakeActivity.this, earthquakes);
// attach the adapter to the recyclerView to populate the items
mRecyclerView.setAdapter(mEarthquakeAdapter);
// set the layout manager to position the items
mRecyclerView.setLayoutManager(new LinearLayoutManager(EarthquakeActivity.this));
Log.e(LOG_TAG,"Recycler view about to be setup");
// click listener for when an item is clicked
mEarthquakeAdapter.setClickListener((view, position) -> searchWeb(earthquakes.get(position).getUrl()));
}
}
}
My View model class
public class MyModel extends ViewModel {
private static final String LOG_TAG = "MyModel";
private MutableLiveData<ArrayList<Earthquake>> mMutableLiveData;
public MutableLiveData<ArrayList<Earthquake>> getEarthquakes() {
mMutableLiveData = new MutableLiveData<>();
// call the API
init();
return mMutableLiveData;
}
public void init() {
// perform the network request on separate thread
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.execute(new Runnable() {
@Override
public void run() {
// create array list of earthquakes
mMutableLiveData.postValue(QueryUtils.fetchEarthquakeData("https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=2021-06-01&limit=300"));
}
});
executorService.shutdown();
}
}
and my Query Utils class relevant method only since the class is big
private static String makeHttpRequest(URL url) throws IOException {
String jsonResponse = "";
// if url null, return
if(url == null) {
return jsonResponse;
}
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
try {
urlConnection= (HttpURLConnection)url.openConnection();
urlConnection.setReadTimeout(10000/*milliseconds*/);
urlConnection.setConnectTimeout(15000/*milliseconds*/);
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// this is being logged again even after screen rotation
Log.v(LOG_TAG,"Network request made");
// if the request was successful(response code 200)
//then read the input stream and parse the output
if(urlConnection.getResponseCode() == 200) {
inputStream = urlConnection.getInputStream();
jsonResponse = readFromStream(inputStream);
}
else{
Log.e(LOG_TAG,"Error Response code: " + urlConnection.getResponseCode());
}
}
catch (IOException e) {
Log.e(LOG_TAG,"Problem retrieving the earthquake JSON results",e);
}
finally {
if(urlConnection != null) {
urlConnection.disconnect();
}
if(inputStream != null) {
inputStream.close();
}
}
return jsonResponse;
Please help me on where I am going wrong. This is very confusing for me now.