【问题标题】:AsyncTask is not returning result quickly enough to main threadAsyncTask 没有足够快地将结果返回给主线程
【发布时间】:2018-06-01 11:05:27
【问题描述】:

我有一个asynctask,它正在从我的 oracle 数据库中获取一个 userPin。在我的主线程中,然后在一个按钮上运行asynctask。将数据库中的值分配给名为userPinRetrieved 的变量。

当我调试这个变量时,它正在接收正确的值。但是,当我正常运行应用程序时,它会收到 null。在做了一些研究并使用Thread.Sleep(x) 之后,我可以看到这是由于 asynctask 没有及时将结果返回给主线程和变量。

有人建议我不要使用Thread.Sleep(x),我有什么替代方案?

这是我的代码:

异步任务:

            String line;
                BufferedReader br=new BufferedReader(new InputStreamReader(con.getInputStream()));
                while ((line=br.readLine()) != null) {
                    JSONObject json = new JSONObject(line);
                    Log.d("Line",line);
                    if (json.getString("userPin") == null){
                        userPinRetrieved = "PIN NOT RECEIVED";
                        Log.d("userpin", userPinRetrieved);
                    } else {
                        userPinRetrieved = json.getString("userPin");
                        Log.d("userpin", userPinRetrieved);
                    }
                }
            }

        } catch (Exception e) {
            Log.v("ErrorAPP", e.toString());
        }
        return "";
    }

    @Override
    protected void onPostExecute(String userPinRetrieved) {
    }

    @Override
    protected void onProgressUpdate(String... values) {
        super.onProgressUpdate(values);
    }
}

登录按钮:

 signIn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            AsyncTaskRunner postReq = new AsyncTaskRunner();
            postReq.execute("start");
            try {
                Thread.sleep(30000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }


            Toast.makeText(UserLogin.this, userPinRetrieved + " " + userPin, Toast.LENGTH_LONG).show();        

            if (userPin.equals(userPinRetrieved)) {
                Toast.makeText(UserLogin.this, "Access Granted!", Toast.LENGTH_SHORT).show();
                Intent intent = new Intent(getApplicationContext(), MainActivity.class);
                startActivity(intent);
                Toast.makeText(UserLogin.this, "Hello " + employee, Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(UserLogin.this, "Access Denied! Incorrect Pin", Toast.LENGTH_SHORT).show();
            }
        }
    });

谁能给点建议?

谢谢

【问题讨论】:

  • 你成功了吗?
  • @LeviAlbuquerque 是的,男人在下面使用了您的答案!谢谢

标签: java android multithreading android-asynctask


【解决方案1】:

AsyncTask 的重点是将处理转移到另一个线程,因为您不知道运行某个任务需要多少时间。您可以在 onPostExecute 方法中处理异步任务的结果。

所以将结果的用法移到那里:

 @Override
    protected void onPostExecute(String userPinRetrieved) {
       if (userPin.equals(userPinRetrieved)) {
                Toast.makeText(UserLogin.this, "Access Granted!", Toast.LENGTH_SHORT).show();
                Intent intent = new Intent(getApplicationContext(), MainActivity.class);
                startActivity(intent);
                Toast.makeText(UserLogin.this, "Hello " + employee, Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(UserLogin.this, "Access Denied! Incorrect Pin", Toast.LENGTH_SHORT).show();
            }
    }

您还可以定义一个在处理完成时将调用的方法:

protected void onPostExecute(String userPinRetrieved) {
       processValue(userPinRetrieved);
    }

在 AsyncTask 中引用活动中的变量时需要小心,如果活动在处理 AsyncTask 期间被破坏,可能会导致内存泄漏。

【讨论】:

  • 现在可以了,谢谢!好的,我了解了内存泄漏,有没有办法防止这种情况发生或更加小心?
  • 在你的情况下,我认为如果你在做 equals 之前检查 userPin 是否为 null 就足够了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-28
  • 1970-01-01
相关资源
最近更新 更多