AsyncTask:如何添加对互联网连接故障的检查?
AsyncTask: how to add check on internet connection faults?
我创建了以下 activity,其中包含一个用于从远程 url 下载 JSON 数据的 AsyncTask。我添加了一个 AlertDialog 来检查用户设备上的互联网连接是否可用,并且我添加了一个超时来处理慢速互联网连接。
这是我的 activity:
public class MyActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_acitivity);
if (isNetworkAvailable(this))
new MyAsyncTask().execute();
else {
AlertDialog.Builder builder;
builder = new AlertDialog.Builder(this);
builder.setCancelable(false);
builder.setTitle("Error");
builder.setMessage("No internet connection");
builder.setPositiveButton("OK", new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
finish();
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
private class MyAsyncTask extends AsyncTask<String, String, String> {
RelativeLayout progress;
@Override
protected void onPreExecute() {
super.onPreExecute();
progress = (RelativeLayout) findViewById(R.id.progressBarlayout);
progress.setOnClickListener(null);
progress.setVisibility(View.VISIBLE);
}
@Override
protected String doInBackground(String... params) {
int timeout = 120;
String jsonString = null;
BasicHttcat1arams basicParams = new BasicHttcat1arams();
HttpConnectionParams.setConnectionTimeout(basicParams, timeout * 1000);
HttpConnectionParams.setSoTimeout(basicParams, timeout * 1000 );
DefaultHttpClient client = new DefaultHttpClient(basicParams);
HttpGet request = new HttpGet("https://www.example.com/data.json");
request.addHeader("Cache-Control", "no-cache");
try {
HttpResponse response = client.execute(request);
HttpEntity entity = response.getEntity();
InputStreamReader in = new InputStreamReader(entity.getContent());
BufferedReader reader = new BufferedReader(in);
StringBuilder sb = new StringBuilder();
String line = "";
while ((line = reader.readLine()) != null) {
sb.acat1end(line);
}
jsonString = sb.toString();
} catch (SocketTimeoutException e) {
e.printStackTrace();
} catch (SocketException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return jsonString;
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
JSONObject json;
try {
json = new JSONObject(s);
p1 = Double.parseDouble(json.getJSONObject("cat1").getJSONObject("subcat1").getString("rcv"));
p2 = Double.parseDouble(json.getJSONObject("cat2").getJSONObject("subcat1").getString("rcv"));
p3 = Double.parseDouble(json.getJSONObject("cat1").getJSONObject("subcat1").getString("avg"));
p4 = Double.parseDouble(json.getJSONObject("cat2").getJSONObject("subcat1").getString("avg"));
p5 = Double.parseDouble(json.getJSONObject("cat1").getJSONObject("subcat2").getString("status"));
p6 = Double.parseDouble(json.getJSONObject("cat2").getJSONObject("subcat2").getString("status"));
} catch (JSONException e) {
e.printStackTrace();
}
progress.setVisibility(View.GONE);
}
}
public static boolean isNetworkAvailable(Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
}
它可以工作,但我的应用程序会崩溃,例如,如果遥控器 url 不可用或在下载网络或 wifi 时离线。
这里是 LogCat:
03-02 15:00:22.466: E/AndroidRuntime(23478): FATAL EXCEPTION: main
03-02 15:00:22.466: E/AndroidRuntime(23478): Process: com.myapp, PID: 23478
03-02 15:00:22.466: E/AndroidRuntime(23478): java.lang.NullPointerException
03-02 15:00:22.466: E/AndroidRuntime(23478): at org.json.JSONTokener.nextCleanInternal(JSONTokener.java:116)
03-02 15:00:22.466: E/AndroidRuntime(23478): at org.json.JSONTokener.nextValue(JSONTokener.java:94)
03-02 15:00:22.466: E/AndroidRuntime(23478): at org.json.JSONObject.<init>(JSONObject.java:155)
03-02 15:00:22.466: E/AndroidRuntime(23478): at org.json.JSONObject.<init>(JSONObject.java:172)
03-02 15:00:22.466: E/AndroidRuntime(23478): at com.myapp.MyActivity$MyAsyncTask.onPostExecute(MyActivity.java:377)
03-02 15:00:22.466: E/AndroidRuntime(23478): at com.myapp.MyActivity$MyAsyncTask.onPostExecute(MyActivity.java:1)
03-02 15:00:22.466: E/AndroidRuntime(23478): at android.os.AsyncTask.finish(AsyncTask.java:632)
03-02 15:00:22.466: E/AndroidRuntime(23478): at android.os.AsyncTask.access0(AsyncTask.java:177)
03-02 15:00:22.466: E/AndroidRuntime(23478): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
03-02 15:00:22.466: E/AndroidRuntime(23478): at android.os.Handler.dispatchMessage(Handler.java:102)
03-02 15:00:22.466: E/AndroidRuntime(23478): at android.os.Looper.loop(Looper.java:136)
03-02 15:00:22.466: E/AndroidRuntime(23478): at android.app.ActivityThread.main(ActivityThread.java:5146)
03-02 15:00:22.466: E/AndroidRuntime(23478): at java.lang.reflect.Method.invokeNative(Native Method)
03-02 15:00:22.466: E/AndroidRuntime(23478): at java.lang.reflect.Method.invoke(Method.java:515)
03-02 15:00:22.466: E/AndroidRuntime(23478): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:732)
03-02 15:00:22.466: E/AndroidRuntime(23478): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:566)
03-02 15:00:22.466: E/AndroidRuntime(23478): at dalvik.system.NativeStart.main(Native Method)
如何处理这些事件?
这个概念叫做异常和异常处理。无法访问 Internet 是一种特殊情况,处理它是将所有此类代码封装到此:
try {
// all your code which can throw an exception
} catch (Exception e) {
// handler; e.g. show an error dialog
}
在 onPostExecute 中创建 JSON 对象之前,您应该检查 String s 是否为空。如果不为 null,请继续您正在做的任何事情,如果为 null,请重新检查互联网连接并重试下载或任何您想要的。
我创建了以下 activity,其中包含一个用于从远程 url 下载 JSON 数据的 AsyncTask。我添加了一个 AlertDialog 来检查用户设备上的互联网连接是否可用,并且我添加了一个超时来处理慢速互联网连接。
这是我的 activity:
public class MyActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_acitivity);
if (isNetworkAvailable(this))
new MyAsyncTask().execute();
else {
AlertDialog.Builder builder;
builder = new AlertDialog.Builder(this);
builder.setCancelable(false);
builder.setTitle("Error");
builder.setMessage("No internet connection");
builder.setPositiveButton("OK", new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
finish();
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
private class MyAsyncTask extends AsyncTask<String, String, String> {
RelativeLayout progress;
@Override
protected void onPreExecute() {
super.onPreExecute();
progress = (RelativeLayout) findViewById(R.id.progressBarlayout);
progress.setOnClickListener(null);
progress.setVisibility(View.VISIBLE);
}
@Override
protected String doInBackground(String... params) {
int timeout = 120;
String jsonString = null;
BasicHttcat1arams basicParams = new BasicHttcat1arams();
HttpConnectionParams.setConnectionTimeout(basicParams, timeout * 1000);
HttpConnectionParams.setSoTimeout(basicParams, timeout * 1000 );
DefaultHttpClient client = new DefaultHttpClient(basicParams);
HttpGet request = new HttpGet("https://www.example.com/data.json");
request.addHeader("Cache-Control", "no-cache");
try {
HttpResponse response = client.execute(request);
HttpEntity entity = response.getEntity();
InputStreamReader in = new InputStreamReader(entity.getContent());
BufferedReader reader = new BufferedReader(in);
StringBuilder sb = new StringBuilder();
String line = "";
while ((line = reader.readLine()) != null) {
sb.acat1end(line);
}
jsonString = sb.toString();
} catch (SocketTimeoutException e) {
e.printStackTrace();
} catch (SocketException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return jsonString;
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
JSONObject json;
try {
json = new JSONObject(s);
p1 = Double.parseDouble(json.getJSONObject("cat1").getJSONObject("subcat1").getString("rcv"));
p2 = Double.parseDouble(json.getJSONObject("cat2").getJSONObject("subcat1").getString("rcv"));
p3 = Double.parseDouble(json.getJSONObject("cat1").getJSONObject("subcat1").getString("avg"));
p4 = Double.parseDouble(json.getJSONObject("cat2").getJSONObject("subcat1").getString("avg"));
p5 = Double.parseDouble(json.getJSONObject("cat1").getJSONObject("subcat2").getString("status"));
p6 = Double.parseDouble(json.getJSONObject("cat2").getJSONObject("subcat2").getString("status"));
} catch (JSONException e) {
e.printStackTrace();
}
progress.setVisibility(View.GONE);
}
}
public static boolean isNetworkAvailable(Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
}
它可以工作,但我的应用程序会崩溃,例如,如果遥控器 url 不可用或在下载网络或 wifi 时离线。
这里是 LogCat:
03-02 15:00:22.466: E/AndroidRuntime(23478): FATAL EXCEPTION: main
03-02 15:00:22.466: E/AndroidRuntime(23478): Process: com.myapp, PID: 23478
03-02 15:00:22.466: E/AndroidRuntime(23478): java.lang.NullPointerException
03-02 15:00:22.466: E/AndroidRuntime(23478): at org.json.JSONTokener.nextCleanInternal(JSONTokener.java:116)
03-02 15:00:22.466: E/AndroidRuntime(23478): at org.json.JSONTokener.nextValue(JSONTokener.java:94)
03-02 15:00:22.466: E/AndroidRuntime(23478): at org.json.JSONObject.<init>(JSONObject.java:155)
03-02 15:00:22.466: E/AndroidRuntime(23478): at org.json.JSONObject.<init>(JSONObject.java:172)
03-02 15:00:22.466: E/AndroidRuntime(23478): at com.myapp.MyActivity$MyAsyncTask.onPostExecute(MyActivity.java:377)
03-02 15:00:22.466: E/AndroidRuntime(23478): at com.myapp.MyActivity$MyAsyncTask.onPostExecute(MyActivity.java:1)
03-02 15:00:22.466: E/AndroidRuntime(23478): at android.os.AsyncTask.finish(AsyncTask.java:632)
03-02 15:00:22.466: E/AndroidRuntime(23478): at android.os.AsyncTask.access0(AsyncTask.java:177)
03-02 15:00:22.466: E/AndroidRuntime(23478): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
03-02 15:00:22.466: E/AndroidRuntime(23478): at android.os.Handler.dispatchMessage(Handler.java:102)
03-02 15:00:22.466: E/AndroidRuntime(23478): at android.os.Looper.loop(Looper.java:136)
03-02 15:00:22.466: E/AndroidRuntime(23478): at android.app.ActivityThread.main(ActivityThread.java:5146)
03-02 15:00:22.466: E/AndroidRuntime(23478): at java.lang.reflect.Method.invokeNative(Native Method)
03-02 15:00:22.466: E/AndroidRuntime(23478): at java.lang.reflect.Method.invoke(Method.java:515)
03-02 15:00:22.466: E/AndroidRuntime(23478): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:732)
03-02 15:00:22.466: E/AndroidRuntime(23478): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:566)
03-02 15:00:22.466: E/AndroidRuntime(23478): at dalvik.system.NativeStart.main(Native Method)
如何处理这些事件?
这个概念叫做异常和异常处理。无法访问 Internet 是一种特殊情况,处理它是将所有此类代码封装到此:
try {
// all your code which can throw an exception
} catch (Exception e) {
// handler; e.g. show an error dialog
}
在 onPostExecute 中创建 JSON 对象之前,您应该检查 String s 是否为空。如果不为 null,请继续您正在做的任何事情,如果为 null,请重新检查互联网连接并重试下载或任何您想要的。