Android 轻松实现网络交互模板

简介:
1.Android与后台交互的模板化方法

2.JSON的使用

3.检查网络连接

4.AsyncTask的使用

我们简单的以登录为例,来实现整个的流程。话不多说,先来看看效果图:




一、通用类的编写


首先,既然要实现交互模板化,最重要的就是要提取出尽可能多的可复用代码。无论是与后台进行什么操作,判断网络是否正常连接、发送请求后得到数据、网络异常时的错误信息提示都是必不可少的。所以我们编写一个通用的CallService类:
[java]  view plain copy
  1. /** 
  2.  * Created by Hyman on 2015/6/11. 
  3.  */  
  4. public class CallService {  
  5.   
  6.     /** 
  7.      * check net connection before call 
  8.      * 
  9.      * @param context 
  10.      * @return 
  11.      */  
  12.     private static boolean checkNet(Context context) {  
  13.         ConnectivityManager connectivity = (ConnectivityManager) context  
  14.                 .getSystemService(Context.CONNECTIVITY_SERVICE);  
  15.         if (connectivity != null) {  
  16.             // 获取网络连接管理的对象  
  17.             NetworkInfo info = connectivity.getActiveNetworkInfo();  
  18.             if (info != null && info.isConnected()) {  
  19.                 // 判断当前网络是否已经连接  
  20.                 if (info.getState() == NetworkInfo.State.CONNECTED) {  
  21.                     return true;  
  22.                 }  
  23.             }  
  24.         }  
  25.         return false;  
  26.     }  
  27.   
  28.     /** 
  29.      * call service by net 
  30.      * 
  31.      * @param urlString url 
  32.      * @param content   a string of json,params 
  33.      * @return the result,a string of json 
  34.      */  
  35.     public static String call(String urlString, String content, Context context) {  
  36.         if (!checkNet(context)) {  
  37.             return null;  
  38.         }  
  39.         try {  
  40.             URL url = new URL(urlString);  
  41.             HttpURLConnection conn = (HttpURLConnection) url.openConnection();  
  42.             conn.setConnectTimeout(5000);  
  43.             conn.setDoOutput(true);  
  44.             conn.setRequestMethod("POST");  
  45.             conn.setRequestProperty("User-Agent""Fiddler");  
  46.             conn.setRequestProperty("Content-Type""application/json");  
  47.             conn.setRequestProperty("Charset""utf-8");  
  48.             OutputStream os = conn.getOutputStream();  
  49.             os.write(content.getBytes());  
  50.             os.close();  
  51.             int code = conn.getResponseCode();  
  52.             if (code == 200) {  
  53.                 BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));  
  54.                 String retData;  
  55.                 String responseData = "";  
  56.                 while ((retData = in.readLine()) != null) {  
  57.                     responseData += retData;  
  58.                 }  
  59.                 in.close();  
  60.                 return responseData;  
  61.             }  
  62.         } catch (MalformedURLException e) {  
  63.             e.printStackTrace();  
  64.         } catch (UnsupportedEncodingException e) {  
  65.             e.printStackTrace();  
  66.         } catch (ProtocolException e) {  
  67.             e.printStackTrace();  
  68.         } catch (IOException e) {  
  69.             e.printStackTrace();  
  70.         }  
  71.         return null;  
  72.     }  
  73.   
  74.     public static void showNetErr(Context context){  
  75.         new AlertDialog.Builder(context)  
  76.                 .setTitle("网络错误")  
  77.                 .setMessage("网络连接失败,请确认网络连接")  
  78.                 .setPositiveButton("确定"new DialogInterface.OnClickListener() {  
  79.                     @Override  
  80.                     public void onClick(DialogInterface arg0, int arg1) {  
  81.   
  82.                     }  
  83.                 }).show();  
  84.     }  
  85.       
  86. }  

其中,判断网络连接状态是借助Android系统提供的ConnectivityManager的方法实现的,借助这个类我们还可以获取更多的连接状态信息,包括当前是用流量还是WIFI等等。

然后,在调用本类核心方法call()时,传入了三个参数,一个是后台服务的url路径,一个是已经组装好的参数,第三个是上下文context。
在这个方法中,我们先去判断网络连接,未连接就直接返回空。否则就使用HttpURLConnection方法向服务器发送请求,再把服务器的返回值返回给调用者。

另一个showNetErr方法就只是简单地跳出一个对话框进行提示。


二、利用Json以及AsyncTask进行交互


我们都知道,在安卓中进行网络操作等等这些耗时的操作,都不能在主线程(即UI线程中)操作,所以我们利用安卓提供的异步机制AsyncTask(或者也可以自己写new Thread + Handler)来进行网络操作。还不了解AsyncTask用法的朋友可以看我的另一篇博客  Android AsyncTask详解
我们以登录为例:
[java]  view plain copy
  1. /** 
  2.  * Created by Hyman on 2015/6/11. 
  3.  */  
  4.   
  5. public class Login {  
  6.   
  7.     private static final String urlString = GetServerUrl.getUrl() + "index.php?r=period/login";  
  8.     private static final String TAG = "Login";  
  9.   
  10.     private ProgressBar progressBar;  
  11.     private Context context;  
  12.   
  13.     private String userName;  
  14.     private String password;  
  15.   
  16.     public Login( Context context,ProgressBar progressBar) {  
  17.         this.progressBar=progressBar;  
  18.         this.context = context;  
  19.     }  
  20.   
  21.     public void login(String userName,String password) {  
  22.         Log.i(TAG, "call login");  
  23.         this.userName=userName;  
  24.         this.password=password;  
  25.         new LoginTask().execute();  
  26.     }  
  27.   
  28.     class LoginTask extends AsyncTask<Void, Void, String> {  
  29.         @Override  
  30.         protected String doInBackground(Void... params) {  
  31.             JSONObject tosendsObject = new JSONObject();  
  32.             Log.i(TAG, "start put json!");  
  33.             try {  
  34.                 //add account info  
  35.                 tosendsObject.put("username", userName);  
  36.                 tosendsObject.put("password", password);  
  37.             } catch (JSONException e) {  
  38.                 e.printStackTrace();  
  39.             }  
  40.             //change json to String  
  41.             String content = String.valueOf(tosendsObject);  
  42.             Log.i(TAG, "send :" + content);  
  43.             String responseData = CallService.call(urlString, content,context);  
  44.             if(responseData==null || responseData.equals("")){  
  45.                 return null;  
  46.             }  
  47.             Log.i(TAG, "res:" + responseData);  
  48.             JSONObject resultObject = null;  
  49.             String result=null;  
  50.             try {  
  51.                 resultObject = new JSONObject(responseData);  
  52.                 result = resultObject.getString("result");  
  53.                 Log.i(TAG, "result:" + result);  
  54.             } catch (JSONException e) {  
  55.                 e.printStackTrace();  
  56.             }  
  57.             return result;  
  58.         }  
  59.   
  60.         @Override  
  61.         protected void onPreExecute() {  
  62.             progressBar.setVisibility(View.VISIBLE);    //show the progressBar  
  63.             super.onPreExecute();  
  64.         }  
  65.   
  66.         @Override  
  67.         protected void onPostExecute(String  result) {  
  68.              progressBar.setVisibility(View.GONE);    //hide the progressBar  
  69.             if(result==null){  
  70.                 CallService.showNetErr(context);  
  71.                 return;  
  72.             }  
  73.             Toast.makeText(context,"result:"+result,Toast.LENGTH_SHORT).show();  
  74.             //here you can do anything you want after login   
  75.         }  
  76.     }  
  77. }  

我们在LoginActivity中初始化这个类的实例,传入上下文以及ProgressBar(用于提高用户体验),再调用login方法传入用户名和密码这两个参数。在进行操作前,onPreExecute方法显示出ProgressBar,在返回结果后,onPostExecute方法再隐藏ProgressBar。

然后我们再看doInBackGroud方法(这个方法听名字就是异步操作啊):我们创建一个JsonObject对象,再使用键值对的方法(类似map)传入参数,最后转成String后一起传给服务器。在得到结果后把服务器返回的json形式的字符串转成JsonObject。如果返回的是空,说明连接有问题,就调用通用类的showNetErr方法。
我把Log截了图,此前不清楚Json格式的朋友可以管中窥豹:



如果有需要传一个list给服务器,还可以使用JsonArray类。比如:
[java]  view plain copy
  1. JSONArray jsonArray = new JSONArray();  
  2. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");  
  3. try {  
  4.     for (PeriodPO peroid : localPeriods) {      //这是一个我自定义的数据结构的list  
  5.         JSONObject periodObject = new JSONObject();  
  6.         periodObject.put("date", sdf.format(peroid.getDate()));  
  7.         periodObject.put("tag", peroid.getTag());  
  8.         periodObject.put("length", peroid.getLength());  
  9.         jsonArray.put(periodObject);            //把每一个对象转成JsonObject,再把每个object放入Array  
  10.     }  
  11.     tosendsObject.put("periods", jsonArray);  
  12.     //add account info  
  13.     tosendsObject.put("username""test");  
  14. catch (JSONException e) {  
  15.     e.printStackTrace();  
  16. }  
相关文章
|
29天前
|
数据库 Android开发 开发者
构建高效Android应用:采用Kotlin协程优化网络请求处理
【2月更文挑战第30天】 在移动应用开发领域,网络请求的处理是影响用户体验的关键环节。针对Android平台,利用Kotlin协程能够极大提升异步任务处理的效率和简洁性。本文将探讨如何通过Kotlin协程优化Android应用中的网络请求处理流程,包括协程的基本概念、网络请求的异步执行以及错误处理等方面,旨在帮助开发者构建更加流畅和响应迅速的Android应用。
|
3月前
|
安全 API Android开发
Android网络和数据交互: 解释Retrofit库的作用。
Android网络和数据交互: 解释Retrofit库的作用。
38 0
|
3月前
|
安全 网络协议 API
Android网络和数据交互: 什么是HTTP和HTTPS?在Android中如何进行网络请求?
Android网络和数据交互: 什么是HTTP和HTTPS?在Android中如何进行网络请求?
29 0
|
28天前
|
Linux Shell 网络安全
【Shell 命令集合 网络通讯 】Linux 与SMB服务器进行交互 smbclient命令 使用指南
【Shell 命令集合 网络通讯 】Linux 与SMB服务器进行交互 smbclient命令 使用指南
40 1
|
3天前
|
Android开发 开发者
Android网络和数据交互: 请解释Android中的AsyncTask的作用。
Android&#39;s AsyncTask simplifies asynchronous tasks for brief background work, bridging UI and worker threads. It involves execute() for starting tasks, doInBackground() for background execution, publishProgress() for progress updates, and onPostExecute() for returning results to the main thread.
3 0
|
3天前
|
网络协议 安全 API
Android网络和数据交互: 什么是HTTP和HTTPS?在Android中如何进行网络请求?
HTTP和HTTPS是网络数据传输协议,HTTP基于TCP/IP,简单快速,HTTPS则是加密的HTTP,确保数据安全。在Android中,过去常用HttpURLConnection和HttpClient,但HttpClient自Android 6.0起被移除。现在推荐使用支持TLS、流式上传下载、超时配置等特性的HttpsURLConnection进行网络请求。
5 0
|
1月前
|
移动开发 JavaScript Android开发
Android与Html5交互
Android与Html5交互
|
2月前
|
XML Android开发 数据格式
安卓和webview交互
安卓和webview交互
25 0
|
3月前
|
JSON Java Android开发
Android网络和数据交互: 请解释Android中的JSON解析库,如Gson。
Android网络和数据交互: 请解释Android中的JSON解析库,如Gson。
24 0
|
1月前
|
机器学习/深度学习 数据采集 人工智能
m基于深度学习网络的手势识别系统matlab仿真,包含GUI界面
m基于深度学习网络的手势识别系统matlab仿真,包含GUI界面
38 0