I am learning Android development and creating an app which calls a REST Service on button click which returns a famous quote from a movie. This quote will be shown on the screen (on TextView).
I have added the user permission to the manifest file:
<uses-permission android:name="android.permission.INTERNET" />
This is my MainActivity.java code
public class MainActivity extends AppCompatActivity {
private static final String LOGTAG = "info";
private static final String QUOTES_API = "https://andruxnet-random-famous-quotes.p.mashape.com/?cat=movies&count=1";
private static final String MASHAPE_KEY = "this-my-api-key";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button newQuoteBtn = (Button) findViewById(R.id.quotesBtn);
newQuoteBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
String quote = getQuote();
Log.i(LOGTAG, quote);
//the quote will be then shown on the text view
}
});
}
private String getQuote() {
try {
URL quotesURL = new URL(QUOTES_API);
HttpsURLConnection conn = (HttpsURLConnection) quotesURL.openConnection();
conn.setRequestProperty("X-Mashape-Key", MASHAPE_KEY);
conn.setRequestProperty("Accept", "application/json");
if(conn.getResponseCode() == 200) {
InputStream inputStream = conn.getInputStream();
InputStreamReader isReader = new InputStreamReader(inputStream, "UTF-8");
BufferedReader buffReader = new BufferedReader(isReader);
StringBuffer json = new StringBuffer(1024);
String tmp="";
while((tmp=buffReader.readLine())!=null) {
json.append(tmp).append("\n");
}
buffReader.close();
JSONObject data = new JSONObject(json.toString());
Log.i(LOGTAG, data.getString("quote"));
return data.getString("quote");
} else {
return null;
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
However when I click the button in the emulator app, nothing happens, it just adds the following message to the logcat
android.os.NetworkOnMainThreadException
From what I am reading, I cannot carry out networking operations on main thread and thats why we have to use AsyncTask. I know that I would need to create a new class which extends AsyncTask but I am still confused about few things:
Q1) Will the new class be an inner class for MainActivity.java or can it be a separate class file as well?
Q2) What will be the params for class GetQuotesClass extends AsyncTask<?, ?, ?>
do I just send <void, void, void>
?
Q3) And how do I call it from my button click? Should I just do new GetQuotesClass().execute()
?
I also read the following comment in another stack overflow thread
AsyncTask should not be used for network activity, because it's tied to the activity, but not the activity lifecycle. Rotating the device with this task is running will cause an exception and crash your app. Use an IntentService that drops data in the sqlite database instead
How can I proceed?