嗨,我是Android应用程序的初学者。我为大学考试做这项工作。我阅读了更多文档,但是在我的活动中显示进度对话框时遇到问题,而asynktask从服务器下载Json String,然后我必须放入listview。 在我的UI线程中,我调用Asynk任务,但线程继续工作,我不能使用httpGet的结果(工作正常)..我理解这使用Log.i(...) 为什么UI线程不会停止并参加结果?我做错了什么? 请帮我。
package my.pack;
import java.util.concurrent.ExecutionException;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
public class TestDialogActivity extends Activity
{
ProgressDialog dialog;
String url = "My URL";
String result= "init";
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DownloadJsonDataTask task = (DownloadJsonDataTask) new DownloadJsonDataTask(result).
execute(url);
try {
String ris = task.get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.i("GET",result);
}
public String requestInfoFromServer() {
String request = null;
HttpConnection http = HttpConnection.getInstance();
http.setHttpClient(url);
request = http.executeRequest();
return request;
}
private class DownloadJsonDataTask extends AsyncTask<String, Integer, String>
{
String Result;
protected void onPreExecute()
{
dialog = new ProgressDialog(TestDialogActivity.this);
dialog.setTitle("Download");
dialog.setMessage("Please wait...");
dialog.setIndeterminate(true);
dialog.show();
}
public DownloadJsonDataTask(String response) {
this.Result=response;
}
protected String doInBackground(String... urls) {
String urldisplay = urls[0];
Log.i("STRING URL:", urldisplay);
String result = requestInfoFromServer();
return Result;
}
protected void onPostExecute(String result) {
this.Result = result;
dialog.dismiss();
}
}
}
答案 0 :(得分:1)
除了Samir Mangroliya。
task.get();
是对调用该方法的线程的阻塞调用。所以在主UI线程上使用它你会阻止它,这是不好的,因为下载smth可能需要几秒钟。因此,系统检测到UI线程被锁定了这么长时间,并使用ANR(应用程序无响应)弹出窗口终止应用程序。要将此移动结果处理修复为AsyncTask的onPostExecute()(至少应该在此时启动结果处理,您可以在此处调用一些主机Activity的方法传递结果)。
答案 1 :(得分:0)
啊我在doInBackground(String... urls)
函数中看到问题,你已经声明了两个名字相似的不同字符串,因为变量名是区分大小写的,一个名为Result
的字符串和另一个字符串完全合法result
因为R和r被视为两个不同的字符,因此它们都具有唯一的名称。虽然这是有效的语法,但是怎么样;这容易出现逻辑错误。我相信这是你遇到问题的地方。在函数调用结束时,您没有将Result
的任何值分配给result
,这也是有效的语法,并且没有指向null变量,因为当您声明Result
它确实放置时在一个空字符串的默认值。所以它会编译并且不会抛出空指针错误,因为变量不是null,即使其中没有字符串数据,指针仍然指向内存中的有效点,因此编译器关注的一切都是好的,它不应该检查字符串的内容只是传递它。同时,您在调用结束之前将所有数据分配到的result
变量将加载所需的所有数据。完全被忽略,直到调用结束,因为没有进一步的命令处理它。然后在调用结束时它被垃圾收集,数据永远不会被传递,因为它没有被告知只传递该变量Result
一个
有意义吗?
答案 2 :(得分:0)
在doInBackground()例程中,将下载的结果保存在成员变量Result中。然后,在onPostExecute()中,您需要阅读Result并更新您的UI。
例如:
private void updateUI(String jsondata)
{
foo = do.something.to.derive.some.data.from.jsondata.
TextView tv = findViewById(R.id.textview1);
tv.setText (foo);
}
private class DownloadJsonDataTask extends AsyncTask<String, Integer, String>
{
String Result = null;
...
protected String doInBackground(String... urls)
{
Result = requestInfoFromServer();
}
protected void onPostExecute(String result)
{
dialog.dismiss();
updateUI(Result);
}
}