Android 輕鬆實現網路互動模板

來源:互聯網
上載者:User

Android 輕鬆實現網路互動模板
看完本文,您可以學到:
1.Android與後台互動的模板化方法

 

2.JSON的使用

3.檢查網路連接

4.AsyncTask的使用

我們簡單的以登入狀態例,來實現整個的流程。話不多說,先來看看:

 

 

 

 

一、通用類的編寫
首先,既然要實現互動模板化,最重要的就是要提取出儘可能多的可複用代碼。無論是與後台進行什麼操作,判斷網路是否正常串連、發送請求後得到資料、網路異常時的錯誤資訊提示都是必不可少的。所以我們編寫一個通用的CallService類:
/** * Created by Hyman on 2015/6/11. */public class CallService {    /**     * check net connection before call     *     * @param context     * @return     */    private static boolean checkNet(Context context) {        ConnectivityManager connectivity = (ConnectivityManager) context                .getSystemService(Context.CONNECTIVITY_SERVICE);        if (connectivity != null) {            // 擷取網路連接管理的對象            NetworkInfo info = connectivity.getActiveNetworkInfo();            if (info != null && info.isConnected()) {                // 判斷當前網路是否已經串連                if (info.getState() == NetworkInfo.State.CONNECTED) {                    return true;                }            }        }        return false;    }    /**     * call service by net     *     * @param urlString url     * @param content   a string of json,params     * @return the result,a string of json     */    public static String call(String urlString, String content, Context context) {        if (!checkNet(context)) {            return null;        }        try {            URL url = new URL(urlString);            HttpURLConnection conn = (HttpURLConnection) url.openConnection();            conn.setConnectTimeout(5000);            conn.setDoOutput(true);            conn.setRequestMethod("POST");            conn.setRequestProperty("User-Agent", "Fiddler");            conn.setRequestProperty("Content-Type", "application/json");            conn.setRequestProperty("Charset", "utf-8");            OutputStream os = conn.getOutputStream();            os.write(content.getBytes());            os.close();            int code = conn.getResponseCode();            if (code == 200) {                BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));                String retData;                String responseData = "";                while ((retData = in.readLine()) != null) {                    responseData += retData;                }                in.close();                return responseData;            }        } catch (MalformedURLException e) {            e.printStackTrace();        } catch (UnsupportedEncodingException e) {            e.printStackTrace();        } catch (ProtocolException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }        return null;    }    public static void showNetErr(Context context){        new AlertDialog.Builder(context)                .setTitle("網路錯誤")                .setMessage("網路連接失敗,請確認網路連接")                .setPositiveButton("確定", new DialogInterface.OnClickListener() {                    @Override                    public void onClick(DialogInterface arg0, int arg1) {                    }                }).show();    }    }

其中,判斷網路連接狀態是藉助Android系統提供的ConnectivityManager的方法實現的,藉助這個類我們還可以擷取更多的串連狀態資訊,包括當前是用流量還是WIFI等等。
然後,在調用本類核心方法call()時,傳入了三個參數,一個是後台服務的url路徑,一個是已經組裝好的參數,第三個是上下文context。 在這個方法中,我們先去判斷網路連接,未串連就直接返回空。否則就使用HttpURLConnection方法向伺服器發送請求,再把伺服器的傳回值返回給調用者。
另一個showNetErr方法就只是簡單地跳出一個對話方塊進行提示。

二、利用Json以及AsyncTask進行互動
我們都知道,在安卓中進行網路操作等等這些耗時的操作,都不能在主線程(即UI線程中)操作,所以我們利用安卓提供的非同步機制AsyncTask(或者也可以自己寫new Thread + Handler)來進行網路操作。還不瞭解AsyncTask用法的朋友可以看我的另一篇部落格 Android AsyncTask詳解。 我們以登入狀態例:
/** * Created by Hyman on 2015/6/11. */public class Login {    private static final String urlString = GetServerUrl.getUrl() + "index.php?r=period/login";    private static final String TAG = "Login";    private ProgressBar progressBar;    private Context context;    private String userName;    private String password;    public Login( Context context,ProgressBar progressBar) {        this.progressBar=progressBar;        this.context = context;    }    public void login(String userName,String password) {        Log.i(TAG, "call login");        this.userName=userName;        this.password=password;        new LoginTask().execute();    }    class LoginTask extends AsyncTask {        @Override        protected String doInBackground(Void... params) {            JSONObject tosendsObject = new JSONObject();            Log.i(TAG, "start put json!");            try {                //add account info                tosendsObject.put("username", userName);                tosendsObject.put("password", password);            } catch (JSONException e) {                e.printStackTrace();            }            //change json to String            String content = String.valueOf(tosendsObject);            Log.i(TAG, "send :" + content);            String responseData = CallService.call(urlString, content,context);            if(responseData==null || responseData.equals("")){                return null;            }            Log.i(TAG, "res:" + responseData);            JSONObject resultObject = null;            String result=null;            try {                resultObject = new JSONObject(responseData);                result = resultObject.getString("result");                Log.i(TAG, "result:" + result);            } catch (JSONException e) {                e.printStackTrace();            }            return result;        }        @Override        protected void onPreExecute() {            progressBar.setVisibility(View.VISIBLE);    //show the progressBar            super.onPreExecute();        }        @Override        protected void onPostExecute(String  result) {             progressBar.setVisibility(View.GONE);    //hide the progressBar            if(result==null){                CallService.showNetErr(context);                return;            }            Toast.makeText(context,"result:"+result,Toast.LENGTH_SHORT).show();            //here you can do anything you want after login         }    }}

我們在LoginActivity中初始化這個類的執行個體,傳入上下文以及ProgressBar(用於提高使用者體驗),再調用login方法傳入使用者名稱和密碼這兩個參數。在進行操作前,onPreExecute方法顯示出ProgressBar,在返回結果後,onPostExecute方法再隱藏ProgressBar。
然後我們再看doInBackGroud方法(這個方法聽名字就是非同步作業啊):我們建立一個JsonObject對象,再使用索引值對的方法(類似map)傳入參數,最後轉成String後一起傳給伺服器。在得到結果後把伺服器返回的json形式的字串轉成JsonObject。如果返回的是空,說明串連有問題,就調用通用類的showNetErr方法。 我把Log截了圖,此前不清楚Json格式的朋友可以管中窺豹:


如果有需要傳一個list給伺服器,還可以使用JsonArray類。比如:
            JSONArray jsonArray = new JSONArray();            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");            try {                for (PeriodPO peroid : localPeriods) {      //這是一個我自訂的資料結構的list                    JSONObject periodObject = new JSONObject();                    periodObject.put("date", sdf.format(peroid.getDate()));                    periodObject.put("tag", peroid.getTag());                    periodObject.put("length", peroid.getLength());                    jsonArray.put(periodObject);            //把每一個對象轉成JsonObject,再把每個object放入Array                }                tosendsObject.put("periods", jsonArray);                //add account info                tosendsObject.put("username", "test");            } catch (JSONException e) {                e.printStackTrace();            }


=============寫在後面========================
我寫完之後,覺得傳參數這件事情也可以放在通用類中,但對如何把那部分代碼巧妙提取出來始終找不到非常好的方法。希望各位朋友可以多提建議,不吝賜教,多謝了!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.