我正在尝试从DoInBackground中的asynctask返回值,但调用get()方法会冻结我的UI。如何将代码重新编写为回调方法? :
public class GetUrlDataTask extends AsyncTask<String, Integer, String> {
String response;
HttpUtils util;
@Override
protected String doInBackground(String... params) {
try {
util = new HttpUtils(params[0]);
response = util.getContent();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return response;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
}
在我的活动中,我得到的结果为response = new GetUrlDataTask().execute("site").get;
答案 0 :(得分:10)
[更新]现在我建议使用注释。使用注释,您可以注入视图,只需几个字母就可以在编译步骤中将函数作为异步过程。查看github上的butterknife库。
您可以创建接口,将其传递给AsyncTask(在构造函数中),然后在onPostExecute中调用方法
例如:
您的界面:
public interface OnTaskCompleted{
void onTaskCompleted();
}
您的活动:
public YourActivity implements OnTaskCompleted{
//your Activity
}
你的AsyncTask:
public YourTask extends AsyncTask<Object,Object,Object>{ //change Object to required type
private OnTaskCompleted listener;
public YourTask(OnTaskCompleted listener){
this.listener=listener;
}
//required methods
protected void onPostExecute(Object o){
//your stuff
listener.onTaskCompleted();
}
}
答案 1 :(得分:6)
如果异步任务需要花费任何相当长的时间(通常是这样),则不应使用.get()。
相反,您可以使用消息/处理程序/服务/等,也可以只使用onPostExecute(Result)方法。
编辑:新代码。根据您的描述,您似乎需要使用界面。如果你需要在另一个类中使用Asynctask,那么接口可能是你最好的选择。
TestTask.java(您单独的Asynctask):
import android.os.AsyncTask;
// Remember to change object type <> to what you need
public class TestTask extends AsyncTask<Object,Object,Object> {
public interface OnTaskCompleted{
void onTaskCompleted();
}
private OnTaskCompleted listener;
public TestTask(OnTaskCompleted listener){
this.listener = listener;
}
protected void onPostExecute(Object o){
// Call the interface method
if (listener != null)
listener.onTaskCompleted();
}
@Override
protected Object doInBackground(Object... params) {
// The sleep() is just to simulate activity and delay
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
}
MainActivity.java(或任何其他活动):
public class MainActivity extends Activity {
private boolean status = false;
private OnTaskCompleted listener = new OnTaskCompleted() {
public void onTaskCompleted() {
status = true;
Toast.makeText(MainActivity.this, "Status: " + status, Toast.LENGTH_SHORT).show();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toast.makeText(MainActivity.this, "Status: " + status, Toast.LENGTH_SHORT).show();
new TestTask(listener).execute("Testing");
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
答案 2 :(得分:1)
我不喜欢在单独的类中使用AsycTask任务,特别是如果你需要使用响应。考虑到作为内部类实现它是多么容易,它使得与响应和局部变量的交互过于困难。
我猜你把它放在自己的类中,这样你就可以重用它。我会考虑将AsycTask保持为内部类,并在doInBackground()中调用可重用的对象/方法。这将使代码保持DRY并允许您的活动通过响应执行所需的操作。
public class MyActivity extends Activity {
TextView textview;
//...
private class GetUrlTask extends AsyncTask<String, Integer, String> {
protected String doInBackground(String... params) {
return new GetHttpResponse().get(params[0]);
}
protected void onPostExecute(String response) {
//Do UI updates...
textview.setText(response);
}
}
}
public class GetHttpResponse {
public String get(String url) {
try {
util = new HttpUtils(url);
response = util.getContent();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return response;
}
}
答案 3 :(得分:0)
你可以这样做:
public class MyActivity extends Activity
{
public void someMethod()
{
// Here you could put up a ProgressDialog
GetUrlDataTask myTask = new GetUrlDataTask();
myTask.execute();
}
public class GetUrlDataTask extends AsyncTask<String, Integer, String>
{
@Override
protected String doInBackground(String... params)
{
String response = null;
HttpUtils util;
try
{
util = new HttpUtils(params[0]);
response = util.getContent();
}
catch (Exception e)
{
e.printStackTrace();
response = e.getMessage();
}
return response;
}
@Override
protected void onPostExecute(String result)
{
// Here you can dismiss the ProgressDialog and display the result
}
}
}