How can I fix 'android.os.NetworkOnMainThreadException'?
NOTE : AsyncTask was deprecated in API level 30.
AsyncTask | Android Developers
This exception is thrown when an application attempts to perform a networking operation on its main thread. Run your code in AsyncTask
:
class RetrieveFeedTask extends AsyncTask<String, Void, RSSFeed> {
private Exception exception;
protected RSSFeed doInBackground(String... urls) {
try {
URL url = new URL(urls[0]);
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
XMLReader xmlreader = parser.getXMLReader();
RssHandler theRSSHandler = new RssHandler();
xmlreader.setContentHandler(theRSSHandler);
InputSource is = new InputSource(url.openStream());
xmlreader.parse(is);
return theRSSHandler.getFeed();
} catch (Exception e) {
this.exception = e;
return null;
} finally {
is.close();
}
}
protected void onPostExecute(RSSFeed feed) {
// TODO: check this.exception
// TODO: do something with the feed
}
}
How to execute the task:
In MainActivity.java
file you can add this line within your oncreate()
method
new RetrieveFeedTask().execute(urlToRssFeed);
Don't forget to add this to AndroidManifest.xml
file:
<uses-permission android:name="android.permission.INTERNET"/>
How to fix NetworkonMainThreadException in Android?
Your Exception
actually tells you exactly what you are doing wrong. You are not using another thread to perform NetworkOperations. Instead, you perform the network operation on your UI-Thread, which cannot (does not) work on Android.
Your code that connects to the url should be executed for example inside an AsyncTasks doInBackground()
method, off the UI-Thread.
Take a look at this question on how to use the AsyncTask: How to use AsyncTask
how do i fix FATAL EXCEPTION:main android.os.NetworkOnMainThreadException
The issue is that inside the AsyncTask's onPostExecute you call the following:
socket.getOutputStream()
This happens on the MainThread and therefore the exception is thrown. Move it to the doInBackground
inside the try catch block
so it looks like this:
public class ConnectPhoneTask extends AsyncTask<String,Void,Boolean> {
@Override
protected Boolean doInBackground(String... params) {
boolean result = true;
try {
InetAddress serverAddr = InetAddress.getByName(params[0]);
socket = new Socket(serverAddr, Constants.SERVER_PORT);//Open socket on server IP and port
if(isConnected) {
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket
.getOutputStream())), true); //create output stream to send data to server
}
} catch (IOException e) {
Log.e("remotedroid", "Error while connecting", e);
result = false;
}
return result;
}
@Override
protected void onPostExecute(Boolean result)
{
isConnected = result;
Toast.makeText(context,isConnected?"Connected to server!":"Error while connecting",Toast.LENGTH_LONG).show();
}
}
Android.OS.NetworkOnMainThreadException: in async/await block
A Task.Run
will get you off the main thread and onto a thread in the default Threadpool:
await Task.Run(async() => {
var url = new URL(viewModel.AvatarUrl);
var connection = url.OpenConnection();
var stream = connection.InputStream;
var logo = await Drawable.CreateFromStreamAsync(stream, viewModel.Title + "_avatar");
GetToolbar.Logo = logo;
});
Android - android.os.NetworkOnMainThreadException
NetworkOnMainThreadException: The exception that is thrown when an application attempts to perform a networking operation on its main thread.
You should call sendfeedback method on asynctask then only above code will work. As webserver is taking lot of time to response main thread becomes unresponsive. To avoid it you should call it on another thread. Hence asynctask is better.
here is link that illustrates how to use asynctask
android.os.NetworkOnMainThreadException and not fix with AsyncTask (jsoup)
Use Asynctask to load the document
public class MainActivity extends AppCompatActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_page);
WebView webView = (WebView) findViewById(R.id.web);
webView.getSettings().setJavaScriptEnabled(true);
new AsyncTask<Void, Void, String>() {
@Override
protected String doInBackground(Void... voids) {
String html = "";
try {
Document document = Jsoup.connect("http://www.memaraneha.ir").get();
Element elements=document.select("div.news-list").first();
html = elements.toString();
} catch (IOException e) {
e.printStackTrace();
}
return html;
}
@Override
protected void onPostExecute(String html) {
String mime = "text/html; charset=utf-8";
String encoding = "utf-8";
webView.loadData(html, mime, encoding);
}
}.execute();
}}
How to resolve android.os.NetworkOnMainThreadException?
The Android OS does not allow heavy process to execute in the main thread/UI Thread because the application will slow down, decreasing performance and the application will lag.
However, you can execute it in an AsyncTask as shown here. Do your process/call your function in the doInBackground
of this asyncTask.
private class Download extends AsyncTask<String, Void, String> {
ProgressDialog pDialog;
@Override
protected void onPreExecute() {
super.onPreExecute();
Log.d("Hi", "Download Commencing");
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Downloading Database...");
String message= "Executing Process";
SpannableString ss2 = new SpannableString(message);
ss2.setSpan(new RelativeSizeSpan(2f), 0, ss2.length(), 0);
ss2.setSpan(new ForegroundColorSpan(Color.BLACK), 0, ss2.length(), 0);
pDialog.setMessage(ss2);
pDialog.setCancelable(false);
pDialog.show();
}
@Override
protected String doInBackground(String... params) {
//INSERT YOUR FUNCTION CALL HERE
return "Executed!";
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.d("Hi", "Done Downloading.");
pDialog.dismiss();
}
}
and call it as such: new Download().execute("");
from another function.
You can do away with the Progress Dialog. I personally like it because I know my process will finish (like data loading) before the user can do anything, ensuring that no error occurs when the user interacts with the program.
How bypass NetworkOnMainThreadException on Kotlin
All of the same classes and methods from Java and the Android SDK are available in Kotlin, so you can just use the exact same thing. The formatting is a bit nicer because of support for SAM constructors among other things.
Thread({
//Do some Network Request
runOnUiThread({
//Update UI
})
}).start()
Related Topics
Changing API Level Android Studio
Android Imageview Zoom-In and Zoom-Out
How to Display Count of Notifications in App Launcher Icon
How to Restart Activity in Android
How to Send Post Request in Json Using Httpclient in Android
Post Multipart Form Data Using Retrofit 2.0 Including Image
Can an Android Toast Be Longer Than Toast.Length_Long
Android Intent Filter: Associate App With File Extension
Android - How to Override the "Back" Button So It Doesn't Finish() My Activity
"Android.View.Windowmanager$Badtokenexception: Unable to Add Window" on Buider.Show()
Using the Android Application Class to Persist Data
How to Do Something Like a Flowlayout in Android
What Does @Hide Mean in the Android Source Code
Passing Android Bitmap Data Within Activity Using Intent in Android
How to Start a Service When .Apk Is Installed For the First Time
Building and Running App Via Gradle and Android Studio Is Slower Than Via Eclipse