我是android的新手。我正在开发一个应用程序,它将从文件中的目标URL加载内容。如果网址不起作用,它将联系我们的服务器以请求正确的网址。如果仍然失败,那么它将从用户输入对话框中询问URL。它会尝试再次初始化。我有这样的代码:
if (initialize(target)!=true) {
JSONObject jsonParam = new JSONObject();
try {
jsonParam.put("sns", getSerial(PREF_NAME));
jsonParam.put("code", pwd);
} catch (JSONException e) {
e.printStackTrace();
}
target = getContent(samURL + "/sam_ip", jsonParam);
if (initialize(target)!=true) {
askIpUserDialog();
}
}
和initialize()如下
private boolean initialize(String url) {
Boolean success = false;
if ((!url.trim().startsWith("http://")) && (!url.trim().startsWith("https://"))) {
url = "http://" + url;
}
if (url.endsWith("/")) {
url = url.substring(0,url.length()-1);
}
String sUrl = url + "/android_view";
URL pUrl;
HttpURLConnection urlConn = null;
try {
DataOutputStream printout;
DataInputStream input;
pUrl = new URL (sUrl);
urlConn = (HttpURLConnection) pUrl.openConnection();
urlConn.setDoInput (true);
urlConn.setDoOutput (true);
urlConn.setUseCaches (false);
urlConn.setRequestProperty("Content-Type","application/json");
urlConn.setRequestProperty("Host", "android.schoolportal.gr");
urlConn.connect();
//Create JSONObject here
JSONObject jsonParam = new JSONObject();
jsonParam.put("snc", serialClient);
jsonParam.put("code", pwd);
printout = new DataOutputStream(urlConn.getOutputStream());
String str = jsonParam.toString();
byte[] data = str.getBytes("UTF-8");
printout.write(data);
printout.flush();
printout.close ();
int HttpResult = urlConn.getResponseCode();
if(HttpResult == HttpURLConnection.HTTP_OK){
success = true;
WebView view=(WebView) this.findViewById(R.id.webView);
view.setWebChromeClient(new WebChromeClient());
view.setWebViewClient(new WebViewClient());
view.getSettings().setJavaScriptEnabled(true);
view.loadUrl(sUrl);
}else{
success = false;
}
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} finally{
if(urlConn!=null)
urlConn.disconnect();
}
return success;
}
我只知道在android中,url连接应该在单独的线程中运行。这就是我收到以下错误的原因:
Caused by: android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork
我的问题是,如何使用AsyncTask来避免错误? 我看到有doInBackground(),我可以在那里放置initialize()函数。 我也看到有onPostExecute()事件,我可以检查doInBackground()的结果,但是我还不明白如何检索放在doInBackground()里面的initialize()的返回?
奖金问题,稍后我想把所有这些工作都放在一个意向服务中。我是否需要使用asynctask? intentservice本身是一个asynctask吗?
答案 0 :(得分:0)
你可以尝试这样的事情,也可以使用不同的线程
final Handler h = new Handler();
Runnable r = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
final File file = new File(path);
Log.i("path",path);
downloadFile(url[j], file);
h.post(new Runnable(){
@Override
public void run() {
txt.setText(""+jp);
jp++;
}
});
}
}
};
new Thread(r).start();
}
private static void downloadFile(String url, File outputFile) {
try {
URL u = new URL(url);
URLConnection conn = u.openConnection();
int contentLength = conn.getContentLength();
Log.i("len","" + contentLength);
Log.i("url1","Streaming from "+url+ "....");
DataInputStream stream = new DataInputStream(u.openStream());
byte[] buffer = new byte[contentLength];
stream.readFully(buffer);
stream.close();
DataOutputStream fos = new DataOutputStream(new FileOutputStream(outputFile));
fos.write(buffer);
fos.flush();
fos.close();
} catch(FileNotFoundException e) {
Log.v("FileError" , e.toString());
return; // swallow a 404
} catch (IOException e) {
Log.v("FileError" , e.toString());
return; // swallow a 404
}
catch (Exception e) {
Log.v("FileError" , e.toString());
return; // swallow a 404
}
}
并且您也无法访问不同线程上的ui元素,您必须使用处理程序或在ui线程上运行。
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try{
this.pd = ProgressDialog.show(this, "Loading..", "Please Wait...", true, false);
new AsyncAction().execute();
}catch (Exception e) {
e.printStackTrace();
}
}
private class AsyncAction extends AsyncTask<String, Void, String> {
protected Void doInBackground(String... args) {
//do your stuff here }
}
}
答案 1 :(得分:0)
网络流量(以及需要一些时间来处理的所有其他逻辑)应始终由后台线程处理,而不应在主线程上处理。
使用ASyncTask执行逻辑。
private class YourTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
// perform your network logic here
return "YourResult";
}
@Override
protected void onPostExecute(String result) {
// Update your screen with the results.
}
}
在代码中调用ASyncTask:
new YourTask().execute("");