安卓数据请求分析和iOS对比
这篇文章总结这两天看的关于网络请求的内容,这部分的内容回合自己熟悉的iOS的进行一个对比学习,大概说说这里总结的内容包括下面的几个部分:
1、WebView的简单使用
2、HttpURLConnection的简单使用
3、OkHttp的简单学习以及数据的解析
4、正确的网络请求处理方式
这里给出一简单的运行的Demo,下面是运行的一个效果图。运行效果图再结合下面的代码总结,把这部分的内容总结起来,也方便自己以后的查询和使用。
WebView其实就是iOSde UIWebView或着WKWebView
这部分的内容其实是比较简单的,简单的代码示例如下:
public class WebViewActivity extends AppCompatActivity { // 这样就能确定你这个Activity需要那些参数进行跳转过来 // static 关键字表示不需要把该类进行实例化就可以访问这个方法。和C 和OC区别 // public 是访问权限 public static void startWebViewActivity(Context context){ Intent intent = new Intent(context,WebViewActivity.class); context.startActivity(intent); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_web_view); WebView webView = (WebView)findViewById(R.id.web_view); webView.getSettings().setJavaScriptEnabled(true);// 设置是否相应JS代码 // 当需要冲一个网页跳转到另一个网页的时候,我们希望目标网页仍然在当前的WebView当中,而不是带打开系统浏览器 webView.setWebViewClient(new WebViewClient()); webView.loadUrl("http://www.baidu.com"); } }
说说上面简单的需要注意的地方:
1、getSettings()属性可以设置WebView的属性,这里只是简单的设置了一个是否支持javaScript脚本
2、注意一下setWebViewClient() 这个方法,这段代码的作用当需要冲一个网页跳转到另一个网页的时候,我们希望目标网页仍然在当前的WebView当中,而不是带打开系统浏览器。
3、这个WebView的使用需要王文网络,要是项目没有处理过网络权限声明,就需要你这样去声明一下:
<!-- 注册网络使用权限 --> <uses-permission android:name="android.permission.INTERNET" />
HttpURLConnection的简单使用
做iOS的同学应该都知道有一个NSURLConnection 或者是NSURLSession(官方推荐我们使用),其实在类比的学习中你会理解的更快一点,这里也就简单的总结一下Android HttpURLConnection的使用,在上面图中看到的请求的百度的数据中我们就是简单的使用HttpURLConnection来完成的,在使用这部分的时候用到了多线程的一点点知识,这个在下面的代码中也能体现出来,来看看下面的代码:
public class HttpUrlConnectionActivity extends AppCompatActivity { private TextView textView; public static void startHttpUrlConnectionActivity(Context context){ Intent intent= new Intent(context,HttpUrlConnectionActivity.class); context.startActivity(intent); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_http_url_connection); Button button = (Button)findViewById(R.id.HttpRequestButton); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { startRequestHttp(); } }); textView = (TextView)findViewById(R.id.respondTextView); } // 请求数据 private void startRequestHttp(){ // 开启一条子线程请求数据 new Thread(new Runnable() { @Override public void run() { HttpURLConnection connection = null; BufferedReader reader = null; try { URL url = new URL("https://www.baidu.com"); connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(8000); connection.setReadTimeout(8000); InputStream in = connection.getInputStream(); // 下面是对获取到的输入流进行读取 reader = new BufferedReader(new InputStreamReader(in)); StringBuilder response = new StringBuilder(); String line; while ((line = reader.readLine())!= null){ response.append(line); } // 展示数据 showRespond(response.toString()); }catch (IOException e){ e.printStackTrace(); }finally { if (reader != null){ try { reader.close(); }catch (IOException e){ e.printStackTrace(); } } if (connection !=null){ connection.disconnect(); } } } }).start(); } // 将内容回到主线程显示到界面上 private void showRespond(final String respondText){ runOnUiThread(new Runnable() { @Override public void run() { // 在这里进行UI的操作,将结果显示到界面上 textView.setText(respondText); } }); } }
下面说说上面这段代码的注意点,这里就说一点,线程的问题:
在iOS中你也知道在子线程中我们是不能更新UI的,在安卓中也是这样子的,在子线程中也是不能更新UI的,在调用请求数据的方法的时候,我们利用 new Thread(new Runnable() 开启了一个子线程,但是当我们看到在更新UI的时候,我们又利用runOnUiThread回到了主线程。当然回到主线程的方式挺多的,下后面的文章中我们再介绍
这里还有一点需要我们先知道的,就是请求完之后数据的回调,在IOS中我们经常用到Block,在安卓中我们会利用接口的形式来完成整个数据的回调。在下面说OkHttp的时候总结这个回调。
OkHttp的简单学习以及数据的解析
OkHttp是安卓使用的比较早也是比较好的一个三方,它的基础就像我们iOS中的AF是一样的,估计也是很多学习安卓的同学接触到的第一个三方,
public class OkHttpActivity extends AppCompatActivity { public TextView textView; public static void startOkHttpActivity(Context context){ Intent intent = new Intent(context,OkHttpActivity.class); context.startActivity(intent); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_ok_http); textView = (TextView)findViewById(R.id.OKHttpRespondTextView); Button button = (Button)findViewById(R.id.OKHttpRequestButton); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // 下面这里的方法其实和iOS中的Block差不多,可以利用Block来理解这段代码 Httputil.sendOKHttpRequest("https://suggest.taobao.com/sug?code=utf-8&q=毛衣&callback=",new okhttp3.Callback(){ @Override public void onFailure(Call call, IOException e) { // 异常处理 } @Override public void onResponse(Call call, Response response) throws IOException { String respondData = response.body().string(); //解析请求到的JSON paraseJSONWithOblect(respondData); } }); } }); /* button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { new Thread(new Runnable() { @Override public void run() { try { // 这个在你POST请求的时候会用到,这里初始化一个RequestBody对象,在下面Request // 里面设置post()传入你的RequestBody对象就实现了POST请求 RequestBody requestBody = new FormBody.Builder() .add("zhangxu","admin") .add("zhangxu2","admin2") .build(); //OkHttpClient OkHttpClient client = new OkHttpClient(); //Request Request request = new Request.Builder() .url("https://suggest.taobao.com/sug?code=utf-8&q=毛衣&callback=") .build(); // Response response = client.newCall(request).execute(); String respondData = response.body().string(); // 展示请求到的数据 showRespond(respondData); //解析请求到的JSON paraseJSONWithOblect(respondData); }catch (Exception e){ e.printStackTrace(); } } }).start(); } });*/ } private void showRespond(final String respond){ runOnUiThread(new Runnable() { @Override public void run() { textView.setText(respond); } }); } // 借助于原生自带的JSONObject 解析JSON数据 private void paraseJSONWithOblect(String jsonData){ try { JSONObject object = new JSONObject(jsonData); JSONArray array = object.getJSONArray("result"); for (int i=0;i<array.length();i++){ JSONArray jsonArray = array.getJSONArray(i); String name = jsonArray.getString(0) + jsonArray.getString(1); Log.d("商品名称+商品ID",name); } }catch (Exception e){ e.printStackTrace(); } } }
上面的这段代码就包含了OkHttp的简单的使用和安卓JSON数据的解析,这里使用到的是一个简单安卓自带的JSONObject的使用,当然这个还不是最简单的安卓JSON数据的解析方法,还有谷歌开源的GSON这个第三方,这个更是简单,这里就不在多做介绍,以后用到的时候自己去查找,再说说XML数据,自己其实用到XML格式的数据不是很多,在很多时候还是JSON格式,在我记得在以前测试微信支付Demo的时候有解析过XML格式的数据,安卓解析XML格式的数据的方法有两种:
1、Pull解析XML格式数据
2、SAX解析XML格式数据
接口的简单总结
这里说一下这个接口的简单的使用,因为这个接口和iOS的Block是挺相似的(使用和作用方面说),正好在我们处理服务器返回的数据结果的时候是经常的用到它的,所以在这里也是简单说一下,以后要是忘记的话可以在这里在进行一个查阅,我们这里就直接简单的使用HttpURLConnection来做一个例子,先来看看它的定义和在需要参数回调的方法里面的简单使用:
//定义的接口,用于数据的回调 public interface HttpCallBackLister{ void onFinish(String response); void onError (Exception response); } // 这是封装的请求数据的方法 static public void sendHttpURLConnectionRequest(final String address, final HttpCallBackLister callBackLister){ new Thread(new Runnable() { @Override public void run() { HttpURLConnection httpURLConnection = null; try { URL url = new URL(address); httpURLConnection = (HttpURLConnection)url.openConnection(); httpURLConnection.setRequestMethod("GET"); httpURLConnection.setConnectTimeout(8000); httpURLConnection.setReadTimeout(8000); httpURLConnection.setDoInput(true); httpURLConnection.setDoOutput(true); InputStream inputStream = httpURLConnection.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); StringBuilder respond = new StringBuilder(); String line; while ((line = reader.readLine())!= null){ respond.append(line); } if (callBackLister != null){ // 在这里回调正确的请求到的数据 callBackLister.onFinish(reader.toString()); } }catch (Exception e){ if (callBackLister != null){ // 在这里回调错误信息 callBackLister.onError(e); } }finally { if (httpURLConnection != null){ httpURLConnection.disconnect(); } } } }).start(); }
再看看这个方法我们再调用的时候是怎样调用的,也是比较的简单,这里的理解和iOS Block的理解是一样的:
Httputil.sendHttpURLConnectionRequest("https://suggest.taobao.com/sug?code=utf-8&q=毛衣&callback=", new Httputil.HttpCallBackLister() { @Override public void onFinish(String response) { // 完成之后的数据处理,在这里就可以进行数据的解析 } @Override public void onError(Exception response) { // 这里是请求数据错误的信息回调,错误的信息会在这里返回 } });
上面差不多就简单介绍完整了Android的整个回调处理的过程,以后再处理安卓项目中肯定还需要再次的封装和处理,这里就不在总结,以后接触到这部分的内容之后再好好的总结!