我有这两节课 . 我的主要Activity和扩展 AsyncTask
的那个,现在在我的主Activity中我需要从 AsyncTask
中的 OnPostExecute()
获得结果 . 如何将结果传递给我的主要活动?
这是示例代码 .
我的主要活动 .
public class MainActivity extends Activity{
AasyncTask asyncTask = new AasyncTask();
@Override
public void onCreate(Bundle aBundle) {
super.onCreate(aBundle);
//Calling the AsyncTask class to start to execute.
asyncTask.execute(a.targetServer);
//Creating a TextView.
TextView displayUI = asyncTask.dataDisplay;
displayUI = new TextView(this);
this.setContentView(tTextView);
}
}
这是AsyncTask类
public class AasyncTask extends AsyncTask<String, Void, String> {
TextView dataDisplay; //store the data
String soapAction = "http://sample.com"; //SOAPAction header line.
String targetServer = "https://sampletargeturl.com"; //Target Server.
//SOAP Request.
String soapRequest = "<sample XML request>";
@Override
protected String doInBackground(String... string) {
String responseStorage = null; //storage of the response
try {
//Uses URL and HttpURLConnection for server connection.
URL targetURL = new URL(targetServer);
HttpURLConnection httpCon = (HttpURLConnection) targetURL.openConnection();
httpCon.setDoOutput(true);
httpCon.setDoInput(true);
httpCon.setUseCaches(false);
httpCon.setChunkedStreamingMode(0);
//properties of SOAPAction header
httpCon.addRequestProperty("SOAPAction", soapAction);
httpCon.addRequestProperty("Content-Type", "text/xml; charset=utf-8");
httpCon.addRequestProperty("Content-Length", "" + soapRequest.length());
httpCon.setRequestMethod(HttpPost.METHOD_NAME);
//sending request to the server.
OutputStream outputStream = httpCon.getOutputStream();
Writer writer = new OutputStreamWriter(outputStream);
writer.write(soapRequest);
writer.flush();
writer.close();
//getting the response from the server
InputStream inputStream = httpCon.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
ByteArrayBuffer byteArrayBuffer = new ByteArrayBuffer(50);
int intResponse = httpCon.getResponseCode();
while ((intResponse = bufferedReader.read()) != -1) {
byteArrayBuffer.append(intResponse);
}
responseStorage = new String(byteArrayBuffer.toByteArray());
} catch (Exception aException) {
responseStorage = aException.getMessage();
}
return responseStorage;
}
protected void onPostExecute(String result) {
aTextView.setText(result);
}
}
14 回答
这个答案可能会迟到,但是当你的
Activity
依赖于AsyncTask
时,我想提一些事情 . 这将有助于您防止崩溃和内存管理 . 正如上面提到的答案中提到的interface
,我们也说它们是回调 . 它们将作为线人工作,但在这些情况下,永远不会发送Activity
或interface
的 strong 引用始终使用 weak 引用 .请参阅下面的屏幕截图,了解这可能导致的问题 .
正如您所看到的,如果我们使用 strong 引用启动
AsyncTask
,则无法保证我们的Activity
/Fragment
在我们获取数据之前将处于活动状态,因此在这些情况下使用WeakReference
会更好,这也有助于内存管理我们永远不会持有我们的Activity
的强大参考,然后它会在失真后有资格进行垃圾收集 .检查下面的代码片段,了解如何使用真棒WeakReference -
MyTaskInformer.java
将作为线人工作的接口 .MySmallAsyncTask.java
AsyncTask做长时间运行的任务,它将使用WeakReference
.MainActivity.java
此类用于在此类上启动AsyncTask
实现interface
,并使用override
此强制方法 .简单:
interface
类,其中String output
是可选的,或者可以是您想要返回的任何变量 .AsyncTask
类,并将接口AsyncResponse
声明为字段:implements
interfaceAsyncResponse
.UPDATE
我没有't know this is such a favourite to many of you. So here'使用
interface
的简单方便的方法 .仍然使用相同的
interface
. 仅供参考,您可以将其合并到AsyncTask
课程中 .在
AsyncTask
类:在
Activity
课程中执行此操作或者,再次在Activity上实现接口
正如你可以看到上面的第一个和第三个解决方案,它需要创建方法
processFinish
,另一个,方法在调用者参数内 . 第三个更整洁,因为没有嵌套的匿名类 . 希望这可以帮助Tip :将
String output
,String response
和String result
更改为不同的匹配类型以获取不同的对象 .您可以在Main类中尝试此代码 . 这对我有用,但我已经用其他方式实现了方法
你可以编写自己的监听器 . 它与HelmiB的答案相同,但看起来更自然:
创建监听器接口:
然后编写异步任务:
最后在activity中实现监听器:
这就是你可以调用asyncTask的方法:
我通过使用线程和处理程序/消息使其工作 . 步骤如下:声明进度对话框
操作完成后,创建一个关闭对话框的功能 .
编写执行细节:
在Activity类中创建一个静态成员 . 然后在
onPostExecute
期间分配值例如,如果AsyncTask的结果是String,请在Activity中创建一个公共静态字符串
public static String dataFromAsyncTask;
然后,在AsyncTask的
onPostExecute
中,只需对主类进行静态调用并设置值 .MainActivity.dataFromAsyncTask = "result blah";
有几个选择:
AsyncTask
类嵌套在Activity
类中 . 假设你没有't use the same task in multiple activities, this is the easiest way. All your code stays the same, you just move the existing task class to be a nested class inside your activity'的课程 .AsyncTask
创建一个自定义构造函数,该构造函数引用您的Activity
. 您可以使用new MyAsyncTask(this).execute(param1, param2)
之类的东西来实例化任务 .嗨,你可以做这样的事情:
在你的Oncreate()中:
`
}`
为什么人们会如此努力 .
这应该足够了 .
不要在异步任务上实现onPostExecute,而是在Activity上实现它:
您需要使用 "protocols" 委托或向
AsynTask
提供数据 .Delegates and Data Sources
委托是一个对象,当该对象遇到程序中的事件时,该对象代表另一个对象或与另一个对象协同工作 . (Apple definition)
protocols are interfaces that define some methods to delegate some behaviors.
Here is a complete example!!!
我觉得下面的方法非常简单 .
我已经声明了一个回调接口
然后创建异步任务以响应所有类型的并行请求
然后单击活动类中的按钮时调用异步任务 .
谢谢
您可以调用
AsyncTask
的get()方法(或重载的get(long, TimeUnit)) . 这种方法会阻止直到AsyncTask
完成其工作,此时它将返回Result
.在创建/启动异步任务和调用
get
方法之间进行其他工作是明智的,否则您不会非常有效地利用异步任务 .您可以在几行中完成,只需在调用AsyncTask时重写onPostExecute . 这是一个例子:
我希望它能帮助你,快乐的编码:)