I am trying to get data from an API in my app but it is showing response below even if I am performing server based operation in separate UI thread. Why is my data not showing?
Below is my JSON response in Postman:
[
{
"term_id": "4",
"name": "Entertainment"
},
{
"term_id": "5",
"name": "Tech & Gadgets"
},
{
"term_id": "6",
"name": "Sports"
},
{
"term_id": "7",
"name": "Health and Fitness Tips"
}
]
It is showing the error below when my app runs:
2020-02-22 12:40:55.881 16118-16118/com.example.flypped E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.flypped, PID: 16118
android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1513)
at com.android.org.conscrypt.Platform.blockGuardOnNetwork(Platform.java:415)
at com.android.org.conscrypt.ConscryptFileDescriptorSocket$SSLInputStream.read(ConscryptFileDescriptorSocket.java:560)
at okio.InputStreamSource.read(Okio.kt:102)
at okio.AsyncTimeout$source$1.read(AsyncTimeout.kt:159)
at okio.RealBufferedSource.request(RealBufferedSource.kt:62)
at okio.RealBufferedSource.require(RealBufferedSource.kt:55)
at okio.RealBufferedSource.readHexadecimalUnsignedLong(RealBufferedSource.kt:299)
at okhttp3.internal.http1.Http1ExchangeCodec$ChunkedSource.readChunkSize(Http1ExchangeCodec.kt:450)
at okhttp3.internal.http1.Http1ExchangeCodec$ChunkedSource.read(Http1ExchangeCodec.kt:429)
at okhttp3.internal.connection.Exchange$ResponseBodySource.read(Exchange.kt:279)
at okio.RealBufferedSource.select(RealBufferedSource.kt:93)
at okhttp3.internal.Util.readBomAsCharset(Util.kt:256)
at okhttp3.ResponseBody.string(ResponseBody.kt:187)
at com.example.flypped.MainActivity$3$1.run(MainActivity.java:241)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7156)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:975)
Suppressed: android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1513)
at com.android.org.conscrypt.Platform.blockGuardOnNetwork(Platform.java:415)
at com.android.org.conscrypt.ConscryptFileDescriptorSocket$SSLInputStream.read(ConscryptFileDescriptorSocket.java:560)
at okio.InputStreamSource.read(Okio.kt:102)
at okio.AsyncTimeout$source$1.read(AsyncTimeout.kt:159)
at okio.RealBufferedSource.request(RealBufferedSource.kt:62)
at okio.RealBufferedSource.require(RealBufferedSource.kt:55)
at okio.RealBufferedSource.readHexadecimalUnsignedLong(RealBufferedSource.kt:299)
at okhttp3.internal.http1.Http1ExchangeCodec$ChunkedSource.readChunkSize(Http1ExchangeCodec.kt:450)
at okhttp3.internal.http1.Http1ExchangeCodec$ChunkedSource.read(Http1ExchangeCodec.kt:429)
at okhttp3.internal.Util.skipAll(Util.kt:337)
at okhttp3.internal.Util.discard(Util.kt:358)
at okhttp3.internal.http1.Http1ExchangeCodec$ChunkedSource.close(Http1ExchangeCodec.kt:471)
at okio.ForwardingSource.close(ForwardingSource.kt:34)
at okhttp3.internal.connection.Exchange$ResponseBodySource.close(Exchange.kt:306)
at okio.RealBufferedSource.close(RealBufferedSource.kt:461)
at kotlin.io.CloseableKt.closeFinally(Closeable.kt:56)
at okhttp3.ResponseBody.string(ResponseBody.kt:186)
... 8 more
Below is my code:
public class Test extends AppCompatActivity {
RecyclerView recycler;
MenuAdapter adapter;
List<MenuModel> list = new ArrayList<>();
ProgressBar prog;
private static final String URL = "https://www.flypped.com/api/Categoery_api";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
recycler = findViewById(R.id.recycler);
prog = findViewById(R.id.prog);
recycler.setHasFixedSize(true);
recycler.setLayoutManager(new LinearLayoutManager(this));
getData();
}
private void getData(){
OkHttpClient client = new OkHttpClient.Builder()
.readTimeout(20, TimeUnit.SECONDS)
.writeTimeout(20,TimeUnit.SECONDS)
.build();
Request request = new Request.Builder().url(URL).build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onResponse(@NotNull Call call, @NotNull final Response response) throws IOException {
runOnUiThread(new Runnable() {
@Override
public void run() {
try {
JSONArray jsonArray = new JSONArray(response.body().string());
if(jsonArray.length() > 0){
prog.setVisibility(View.INVISIBLE);
for(int i =0;i<jsonArray.length();i++){
JSONObject jsonObject = jsonArray.getJSONObject(i);
String str1 = jsonObject.getString("name");
String str2 = jsonObject.getString("term_id");
MenuModel model = new MenuModel(str1,str2);
list.add(model);
}
adapter = new MenuAdapter(list,getApplicationContext());
recycler.setAdapter(adapter);
}
} catch (JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
@Override
public void onFailure(@NotNull Call call, @NotNull final IOException e) {
runOnUiThread(new Runnable() {
@Override
public void run() {
prog.setVisibility(View.INVISIBLE);
Toast.makeText(getApplicationContext(),e.getMessage(),Toast.LENGTH_SHORT).show();
}
});
}
});
}
}
Why is this error showing even though I am using network operations in a separate UI thread?
The problem you are having is because you are trying to perform a network operation on the main thread.
If you look at the first line of your stacktrace you can see that:
Process: com.example.flypped, PID: 16118 android.os.NetworkOnMainThreadException
To fix this, you can run your code inside of an AsyncTask.
Note : Deprecated in Android R
private class TestTask extends AsyncTask<YOUR PARAMETERS> {
protected Long doInBackground(Params) {
//Your logic
}
protected void onProgressUpdate(Integer... progress) {
//Update progress
}
protected void onPostExecute(Long result) {
}
}
To execute an AsyncTask, you write:
new TestTask().execute(YOUR_PARAMS);