Apologies if this is a simple question but I am very new to this and still learning.
I have an app and when my users click the button to login after entering their details, it is crashing with android.os.NetworkOnMainThreadException I have discovered this is because I am performing a network operation on the main thread and to resolve I need to use AsyncTask, I am stuck however with the syntax.
Here is my code after the button is clicked, calls a function to connect and then parses json into sqlite db.
// Login button Click Event
btnLogin.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
String email = inputEmail.getText().toString();
String password = inputPassword.getText().toString();
UserFunctions userFunction = new UserFunctions();
JSONObject json = userFunction.loginUser(email, password);
// check for login response
try {
if (json.getString(KEY_SUCCESS) != null) {
loginErrorMsg.setText("");
String res = json.getString(KEY_SUCCESS);
if(Integer.parseInt(res) == 1){
// user successfully logged in
// Store user details in SQLite Database
DatabaseHandler db = new DatabaseHandler(getApplicationContext());
JSONObject json_user = json.getJSONObject("user");
// Clear all previous data in database
userFunction.logoutUser(getApplicationContext());
db.addUser(json_user.getString(KEY_NAME), json_user.getString(KEY_EMAIL), json.getString(KEY_UID), json_user.getString(KEY_CREATED_AT));
// Launch Dashboard Screen
Intent dashboard = new Intent(getApplicationContext(), DashboardActivity.class);
// Close all views before launching Dashboard
dashboard.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(dashboard);
// Close Login Screen
finish();
}else{
// Error in login
loginErrorMsg.setText("Incorrect username/password");
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
How do I change this to the correct class ? I am not passing URL's etc. I think it needs to be something like this , but I am really struggling to get the syntax right.
Many thanks!!!
class login extends AsyncTask<Void, Void, Void> {
private Exception exception;
protected ??? doInBackground(???) {
try {
Example Code syntax for Android AsyncTask:The AsyncTask instance must be created and invoked in the UI thread. AsyncTask can be called only once. Executing it again will throw an exception. You can change the return parameter type as well as request parameter type according to your requirement.
AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
AsyncTask is used to perform time talking operations in android, but it's marked as deprecated from android 11.
Official Reason for Deprecation of AsyncTask AsyncTask was intended to enable proper and easy use of the UI thread. However, the most common use case was for integrating into UI, and that would cause Context leaks, missed callbacks, or crashes on configuration changes.
It would be something like this
public class TalkToServer extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
/*
* do things before doInBackground() code runs
* such as preparing and showing a Dialog or ProgressBar
*/
}
@Override
protected void onProgressUpdate(Void... values) {
/*
* updating data
* such a Dialog or ProgressBar
*/
}
@Override
protected Void doInBackground(Void... params) {
//do your work here
return null;
}
@Override
protected void onPostExecute(Void result) {
/*
* do something with data here
* display it or send to mainactivity
* close any dialogs/ProgressBars/etc...
*/
}
}
Then you can execute it with
TalkToServer myTask = new MyTask(); // can add params for a constructor if needed
myTask.execute(); // here is where you would pass data to doInBackground()
You may not need onProgressUpdate()
or onPreExecute()
if you aren't using them to show a Dialog
, progress, or other tasks before or during doInBackground()
.
onPreExecute() can be used to initialize and show a ProgressDialog
. Then it could be dismissed in onPostExecute()
After a task finishes
onPostExecute()
will be called. If the class is an inner-class of your Activity
then you can update UI
elements there or call a function to run code once the task finishes. If it is a separate file than the Activity
then you can use an interface
and create a callBack
to the Activity
and run code there once the task finishes.
This answer talks about using an interface for a callback if you need
Make sure any UI
updating is done in any method besides doInBackground()
or sent back to the Activity
in any function besides doInBackground()
. Heavy-lifting such as network operations should be done in doInBackground()
.
Also, be sure to read through the AsyncTask Docs completely. Especially the Threading Rules
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With