安卓中进行网络访问获取结果时一般都是以回调的方式来获取网络访问结果,例如:
public static void getBusiness(final String url, final OnLoadFinish<String> listener){
new Thread(){
public void run(){
try {
URL u = new URL(url);
HttpURLConnection connection = (HttpURLConnection) u.openConnection();
connection.setDoInput(true);
connection.setRequestMethod("GET");
connection.connect();
InputStream in = connection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in, "utf8"));
final StringBuilder sb = new StringBuilder();
String line = null;
while((line = br.readLine())!=null){
sb.append(line);
}
new Handler(Looper.getMainLooper()).post(new Runnable(){
public void run(){
listener.onFinish(sb.toString());
}
});
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
}
但是有的时候,也许以方法返回值的方式将网络结果返回更符合使用习惯。这里可以借助Callable或FutureTask来实现。
public static String getSyncBusiness(final String url){
try {
FutureTask<String> task = new FutureTask<String>(new Callable<String>() {
@Override
public String call() throws Exception {
URL u = new URL(url);
HttpURLConnection connection = (HttpURLConnection) u.openConnection();
connection.setDoInput(true);
connection.setRequestMethod("GET");
connection.connect();
InputStream in = connection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in, "utf8"));
final StringBuilder sb = new StringBuilder();
String line = null;
while((line = br.readLine())!=null){
sb.append(line);
}
return sb.toString();
}
});
new Thread(task).start();
return task.get();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("网络访问错误");
}
}
FutureTask本身实现了Future接口和Runnable接口,同时构造器接收一个Callable类型的参数。正是因为FutureTask实现了Runnable接口,因此可以由Thread驱动在非工作线程中进行网络访问。
如果直接使用Callable接口的话,需要线程池来进行驱动,Thread是不能驱动Callable任务的。
public static String getSyncBusiness2(final String url){
try {
Callable<String> callable = new Callable<String>() {
@Override
public String call() throws Exception {
URL u = new URL(url);
HttpURLConnection connection = (HttpURLConnection) u.openConnection();
connection.setDoInput(true);
connection.setRequestMethod("GET");
connection.connect();
InputStream in = connection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in, "utf8"));
final StringBuilder sb = new StringBuilder();
String line = null;
while((line = br.readLine())!=null){
sb.append(line);
}
return sb.toString();
}
};
ExecutorService exec = Executors.newFixedThreadPool(1);
Future<String> task = exec.submit(callable);
return task.get();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("网络访问错误");
}
}
需要注意的是,无论是利用FutureTask还是Callable,在网络访问结果返回前都将是阻塞住调用线程的,因此必须考虑到安卓的ANR问题。