使用异步任务

Posted

技术标签:

【中文标题】使用异步任务【英文标题】:Using AsyncTask 【发布时间】:2013-09-24 17:40:07 【问题描述】:

抱歉,如果这是一个简单的问题,但我对此很陌生并且仍在学习。

我有一个应用程序,当我的用户在输入他们的详细信息后单击按钮登录时,它会因 android.os.NetworkOnMainThreadException 而崩溃 我发现这是因为我在主线程上执行网络操作并解决我需要使用 AsyncTask,但是我被语法卡住了。

这是我单击按钮后的代码,调用一个函数进行连接,然后将 json 解析为 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();
            
        
    );

如何将其更改为正确的类?我没有传递 URL 等。我认为它需要是这样的,但我真的很难让语法正确。

非常感谢!!!

class login extends AsyncTask<Void, Void, Void> 

    private Exception exception;

    protected ??? doInBackground(???) 
        try 

【问题讨论】:

为了FSM!!! eclipse 中的(Alt+Shift+s) -&gt; Override/Implement Methods 会停止工作吗?或(Alt + Insert -&gt; Override Methods) 在 Android studio/IDEA 中? @Gary 你还有问题吗? AsyncTask Android example的可能重复 本教程一定能帮到你Simple AsyncTask example - explanation 【参考方案1】:

应该是这样的

   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...
        */
   

然后你可以执行它

TalkToServer myTask = new MyTask(); // can add params for a constructor if needed
myTask.execute(); // here is where you would pass data to doInBackground()

如果您不使用Dialog、进度或doInBackground() 之前或期间的其他任务,则可能不需要onProgressUpdate()onPreExecute()

onPreExecute() 可用于初始化并显示ProgressDialog。然后可以在onPostExecute() 中解散它

任务完成后

onPostExecute() 将被调用。如果该类是您的Activity 的内部类,那么您可以在那里更新UI 元素,或者在任务完成后调用函数来运行代码。如果它是与Activity 不同的文件,那么您可以使用interface 并为Activity 创建一个callBack,并在任务完成后在那里运行代码。

This answer talks about using an interface for a callback if you need

确保任何UI 更新是在doInBackground() 之外的任何方法中完成的,或者在doInBackground() 之外的任何函数中发送回Activity。网络操作等繁重的工作应该在doInBackground()完成。

另外,请务必通读AsyncTask Docs。尤其是线程规则

【讨论】:

不管怎样,我只花了我 2 美分来了解 super.onPostExecute(...)super.onProgressUpdate(...)super.onPreExecute() ...我见过很多例子,其中 ppls 在自己的 AsyncTask 实现中调用它们...我有一个问题: 为什么...所有这些方法在基类/超类中都是空的... 谢谢...但我在公共类 TalkToServer 上仍有一个错误 extends AsyncTask --- 本地类 TalkToServer 的非法修饰符;只允许抽象或最终 它是在方法之外声明的吗?你是如何初始化它的?

以上是关于使用异步任务的主要内容,如果未能解决你的问题,请参考以下文章

微服务架构中的任务调度:在 SpringBoot 框架中使用异步任务,定时任务和邮件任务

Android AsyncTask异步任务的使用

Django项目中使用celery做异步任务

SpringBoot异步任务

Celery异步任务框架

android:异步任务asyncTask介绍及异步任务下载图片(带进度条)