Using AsyncTask

匿名 (未验证) 提交于 2019-12-03 02:08:02

问题:

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 { 

回答1:

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



文章来源: Using AsyncTask
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!