1. 程式人生 > >android與伺服器互動總結(json,post,xUtils,Volley,Gson)

android與伺服器互動總結(json,post,xUtils,Volley,Gson)

(最後一次更新2016 - 12 - 21)

更新內容:由於android 6.0完全拋棄了HttpClinet,所以,原生的網路請求,建議使用HttpURLConnection,本文的第三方框架,都是去年比較老的,現在xutils都更新到xutils3了,沒有大檔案的網路請求,使用volley就夠了,最近的網路框架有Retrofit和OkHttp等,都是風生水起,建議使用去github搜尋框架,百度谷歌使用方法,本次更新了HttpURLConnection的請求使用以及Gson的解析方法。寫了一個工具類,湊合看吧

從無到有,從來沒有接觸過Json,以及與伺服器的互動。然後慢慢的熟悉,瞭解了一點。把我學到的東西簡單的做個總結,也做個記錄,萬一以後用到,就不用到處找了。

主要是簡單的資料互動,就是字串的互動,傳資料,取資料。剛開始用的普通方法,後來研究了下xUtils框架。

伺服器端有人開發,這一塊不是我負責,所以我只負責客戶端傳資料以及接受資料後的處理就OK了。

傳遞資料的形式,主要是看服務端的介面怎麼寫,伺服器是接受JSON字串,還是要form表單格式(我認為form表單格式就是鍵值對)。

xUtils:

還有就是,你如果想使用library到自己的專案下,注意一點主專案檔案和library庫檔案,必須在同一個資料夾目錄下,否則執行專案是報錯的

Volley:

還有一些框架:KJFeame和Afinal

KJFrame:

0.HttpUrlConnection的使用

package njj.com.myapplication1;

import android.text.TextUtils;
import android.util.Log;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created by jian on 2016/12/15.
 */
public class HttpUtil {

    String Path = "http://test.bidit.cn/api/getServerTime/?clientType=1&version=4&versionName=test_2.0.2";

    /**
     * @param address
     * @param listener
     * @return 將String 改為 void。因為網路請求是耗時操作,我們需要在子執行緒中執行,
     * 但是子執行緒無法通過return語句來返回資料,也不能在子執行緒中更新UI,所以利用回撥來實現
     * 除非使用runOnUiThread()方法。
     */
    public static void sendHttpRequest(final String address,
                                       final Map<String, String> params,
                                       final HttpCallbackListener listener) {
        HttpURLConnection connection = null;
        try {
            URL url = new URL(address);
            connection = (HttpURLConnection) url.openConnection();

            // 請求方式:GET 或者 POST
            connection.setRequestMethod("POST");
            // 設定讀取超時時間
            connection.setReadTimeout(5000);
            // 設定連線超時時間
            connection.setConnectTimeout(5000);
            // 接收輸入流
            connection.setDoInput(true);
            // 啟動輸出流,當需要傳遞引數時開啟
            connection.setDoOutput(true);
            /*
             * 新增Header,告訴服務端一些資訊,比如讀取某個檔案的多少位元組到多少位元組,是不是可以壓縮傳輸,
             * 客戶端支援的編碼格式,客戶端型別,配置,需求等。
             */
//            connection.setRequestProperty("Connection","Keep-Alive"); // 維持長連線
//            connection.setRequestProperty("Content-Type", "text/plain; charset=utf-8");
            // 新增引數, 寫入引數之前不能讀取伺服器響應,如獲得code
            addParams(address, connection.getOutputStream(), params);

            // 發起請求
            connection.connect();

            /**
             * getInputStream實際才傳送請求,並得到網路返回的輸入流
             */
            InputStream is = connection.getInputStream();
            // 伺服器響應code,200表示請求成功並返回
            int code = connection.getResponseCode();
            if (code != HttpURLConnection.HTTP_OK) {
                listener.onError("錯誤code = " + code);
                return;
            }

            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            StringBuilder response = new StringBuilder();

            String line;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }

            if (listener != null) {
                listener.onSuccess(response.toString());
            }
            /*return response.toString();*/
        } catch (Exception e) {
            e.printStackTrace();
            if (listener != null) {
                listener.onError(e.toString());
            }
            /*return e.getMessage();*/
        } finally {
            if (connection != null) connection.disconnect();
        }
    }

    /**
     * 使用NameValuePair和BasicNameValuePair需要在build.gradle中的android閉包中新增:
     * useLibrary 'org.apache.http.legacy'
     */
    private static void addParams(String address, OutputStream output, Map<String, String> params)
            throws IOException {
        List<NameValuePair> paramList = new ArrayList<>();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            paramList.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
        }

        StringBuilder paramStr = new StringBuilder();
        for (NameValuePair pair : paramList) {
            if (!TextUtils.isEmpty(paramStr)) {
                paramStr.append("&");
            }
            paramStr.append(URLEncoder.encode(pair.getName(), "UTF-8"));
            paramStr.append("=");
            paramStr.append(URLEncoder.encode(pair.getValue(), "UTF-8"));
        }

        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output, "UTF-8"));
        // 將引數寫入到輸出流
        writer.write(paramStr.toString());
        // 重新整理物件輸出流,將任何位元組都寫入潛在的流中
        writer.flush();
        // 關閉流物件。此時,不能再向物件輸出流寫入任何資料,先前寫入的資料存在於記憶體緩衝區中,
        // 之後呼叫的getInputStream()函式時才把準備好的http請求正式傳送到伺服器
        writer.close();

        /**
         * 列印請求全路徑的url
         */
        StringBuilder urlStr = new StringBuilder(address);
        urlStr.append("?");
        urlStr.append(paramStr.toString());
        Log.i("niejianjian", " -> url -> " + urlStr);
    }

    public interface HttpCallbackListener {
        void onSuccess(String response);

        void onError(String errorInfo);
    }

}
使用方式:
package njj.com.myapplication1;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by jian on 2016/12/21.
 */
public class MainActivity extends AppCompatActivity {

    Button mButton;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mButton = (Button) findViewById(R.id.button);
        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
//                        String Path = "http://test.bidit.cn/api/sysconfig/Android_minValidVersion/?clientType=1&version=4&versionName=test_2.0.2";
                        String path = "http://test.niejian.cn/api/"; // 假的,並沒有這個地址
                        Map<String, String> params = new HashMap<>();
                        params.put("username", "niejianjian");
                        params.put("password", "123456");
                        HttpUtil.sendHttpRequest(path, params, new HttpUtil.HttpCallbackListener() {
                            @Override
                            public void onSuccess(String response) {
                                Log.i("niejianjian", " -> onSuccess -> " + response);
                            }

                            @Override
                            public void onError(String info) {
                                Log.i("niejianjian", " -> onError -> " + info);
                            }
                        });
                    }
                }).start();
            }
        });

    }
}

下載檔案
package preview.ruby.com.myapplication;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.LinearLayout;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class MainActivity extends AppCompatActivity {

    public static final String ROOT_PATH = Environment.getExternalStorageDirectory().toString();
    private static final String PATH = File.separatorChar + "ijizhe";
    private static final String DOWN_URL = "http://download.ijizhe.cn/ijizhe-2.0.6-ijizhe.apk";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        downFile();
                    }
                }).start();

            }
        });

        ((Button) findViewById(R.id.button1)).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                File file = new File(ROOT_PATH + PATH + File.separator + "ijizhe.apk");
                Intent intent1 = new Intent(Intent.ACTION_VIEW);
                // Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
                intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

                intent1.setDataAndType(
                        Uri.parse("file://" + ROOT_PATH + PATH + "/ijizhe.apk"),
                        "application/vnd.android.package-archive");
                startActivity(intent1);
            }
        });
    }

    public void downFile() {

        URL url = null;
        try {
            url = new URL(DOWN_URL);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            //設定超時間為3秒
            conn.setConnectTimeout(3 * 1000);
            //防止遮蔽程式抓取而返回403錯誤
            conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
            //得到輸入流
            InputStream inputStream = conn.getInputStream(); // 傳送請求,獲得伺服器返回的輸入流

            //獲取自己陣列
            byte[] getData = readInputStream(inputStream); // 將請求到的寫入到本地,此過程開始耗時。
            Log.i("niejianjian", " -> downFile -> 4 -> " + conn.getResponseCode());
            //檔案儲存位置
            File saveDir = new File(ROOT_PATH + PATH);
            if (!saveDir.exists()) {
                saveDir.mkdir();
            }
            File file = new File(saveDir + File.separator + "ijizhe.apk");
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(getData);
            if (fos != null) {
                fos.close();
            }
            if (inputStream != null) {
                inputStream.close();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 從輸入流中獲取位元組陣列
     *
     * @param inputStream
     * @return
     * @throws IOException
     */
    public static byte[] readInputStream(InputStream inputStream) throws IOException {
        byte[] buffer = new byte[1024];
        int len = 0;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while ((len = inputStream.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
        bos.close();
        return bos.toByteArray();
    }

}
新增許可權
    <uses-permission android:name="android.permission.INTERNET"></uses-permission>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
android6.0需要對STORAGE許可權申請執行時許可權  :  http://blog.csdn.net/u012975370/article/details/49799041#t33

1.要傳送到伺服器端的是以JSON字串的形式傳送的。(下面的格式)

{"device":"hwG620S-UL00","brand":"HUAWEI","model":"G620S-UL00","imei":"865242025001258","romversion":"G620S-UL00V100R001C17B264"}
private void sendData1() {
		new Thread(new Runnable() {
			@Override
			public void run() {
				Log.i(TEST_TAG, "2222");
				try {

					HttpPost post = new HttpPost(ACTIVATE_PATH);// post請求
					// 先封裝一個JSON物件
					JSONObject param = new JSONObject();
					param.put("romversion", serviceInfoMap.get("romversion"));
					param.put("brand", serviceInfoMap.get("brand"));
					param.put("model", serviceInfoMap.get("model"));
					param.put("device", serviceInfoMap.get("device"));
					param.put("imei", serviceInfoMap.get("imei"));
					// 繫結到請求Entry
					StringEntity se = new StringEntity(param.toString(),
							"utf-8");
					post.setEntity(se);
					Log.i(TEST_TAG, "JSON為---> " + param.toString());
					// JSON為--->
					// {"device":"hwG620S-UL00","brand":"HUAWEI","model":"G620S-UL00","imei":"8<span style="white-space:pre">					</span>// 65242025001258","romversion":"G620S-UL00V100R001C17B264"}

					// 傳送請求
					HttpParams params = new BasicHttpParams();
					DefaultHttpClient localDefaultHttpClient = new DefaultHttpClient(
							params);
					localDefaultHttpClient.getParams().setParameter(
							"http.connection.timeout", Integer.valueOf(30000));
					localDefaultHttpClient.getParams().setParameter(
							"http.socket.timeout", Integer.valueOf(30000));
					HttpResponse response = localDefaultHttpClient
							.execute(post);
					// 得到應答的字串,這也是一個JSON格式儲存的資料
					String retStr = EntityUtils.toString(response.getEntity());
					// 生成JSON物件
					JSONObject result = new JSONObject(retStr);
					int status_value = response.getStatusLine().getStatusCode();
					Log.i(TEST_TAG, "" + status_value);
					String statusValue = "";
					statusValue = result.getString("status");
					Log.i(TEST_TAG, statusValue);
					if (!statusValue.equals("")) {
						// 如果不為空,說明取到了資料,然後就先關閉進去條
						mHandler.sendEmptyMessage(CLOSE_DIALOG);
						// 然後判斷值是否==1,來決定彈出哪個dialog
						// 啟用成功,就把值傳到系統的contentprovider,然後永久儲存
						if (Integer.parseInt(statusValue) == 1) {
							mHandler.sendEmptyMessage(SHOW_SUCCESS);
							// 將值設定成1
							Settings.System.putInt(getContentResolver(),
									SETTING_MODIFY_NAME, 1);
						} else { // 只要是不為1外的其他值,都算失敗,彈出失敗的dialog
							mHandler.sendEmptyMessage(SHOW_FAILURE);
						}
					}

				} catch (UnsupportedEncodingException e) {
					e.printStackTrace();
				} catch (ClientProtocolException e) {
					e.printStackTrace();
					mHandler.sendEmptyMessage(CONTENT_STATUS);
				} catch (SocketException e) {
					mHandler.sendEmptyMessage(CONTENT_STATUS);
				} catch (IOException e) {
					mHandler.sendEmptyMessage(CONTENT_STATUS);
					e.printStackTrace();
				} catch (JSONException e) {
					mHandler.sendEmptyMessage(CONTENT_STATUS);
					e.printStackTrace();
				}
			}
		}).start();
	}

2.以form表單的格式傳送到服務端

將傳遞的資料打印出來,格式是這樣的,和json串是不一樣的。[romversion=G620S-UL00V100R001C17B264, brand=HUAWEI, model=G620S-UL00, device=hwG620S-UL00, imei=865242024756522]

private void sendData1() {
		new Thread(new Runnable() {
			@Override
			public void run() {
				Log.i(TEST_TAG, "2222");
				try {

					HttpPost post = new HttpPost(ACTIVATE_PATH);// post請求
					// 設定新增物件
					List<NameValuePair> paramsForm = new ArrayList<NameValuePair>();
					paramsForm.add(new BasicNameValuePair("romversion",
							serviceInfoMap.get("romversion")));
					paramsForm.add(new BasicNameValuePair("brand",
							serviceInfoMap.get("brand")));
					paramsForm.add(new BasicNameValuePair("model",
							serviceInfoMap.get("model")));
					paramsForm.add(new BasicNameValuePair("device",
							serviceInfoMap.get("device")));
					paramsForm.add(new BasicNameValuePair("imei",
							serviceInfoMap.get("imei")));
					Log.i(TEST_TAG, paramsForm.toString());
					post.setEntity(new UrlEncodedFormEntity(paramsForm,
							HTTP.UTF_8));

					// 傳送請求
					HttpParams params = new BasicHttpParams();
					DefaultHttpClient localDefaultHttpClient = new DefaultHttpClient(
							params);
					localDefaultHttpClient.getParams().setParameter(
							"http.connection.timeout", Integer.valueOf(30000));
					localDefaultHttpClient.getParams().setParameter(
							"http.socket.timeout", Integer.valueOf(30000));
					HttpResponse response = localDefaultHttpClient
							.execute(post);
					// 得到應答的字串,這也是一個JSON格式儲存的資料
					String retStr = EntityUtils.toString(response.getEntity());
					// 生成JSON物件
					JSONObject result = new JSONObject(retStr);
					int status_value = response.getStatusLine().getStatusCode();
					Log.i(TEST_TAG, "" + status_value);
					String statusValue = "";
					statusValue = result.getString("status");
					Log.i(TEST_TAG, "status: " + statusValue);
					Log.i(TEST_TAG, "datatime: " + result.getString("datatime"));
					Log.i(TEST_TAG, "message: " + result.getString("message"));
					if (!statusValue.equals("")) {
						// 如果不為空,說明取到了資料,然後就先關閉進去條
						mHandler.sendEmptyMessage(CLOSE_DIALOG);
						// 然後判斷值是否==1,來決定彈出哪個dialog
						// 啟用成功,就把值傳到系統的contentprovider,然後永久儲存
						if (Integer.parseInt(statusValue) == 1) {
							// 將值設定成1。需要加許可權
							Settings.System.putInt(getContentResolver(),
									SETTING_MODIFY_NAME, 1);
							mHandler.sendEmptyMessage(SHOW_SUCCESS);
						} else { // 只要是不為1外的其他值,都算失敗,彈出失敗的dialog
							mHandler.sendEmptyMessage(SHOW_FAILURE);
						}
					}

				} catch (UnsupportedEncodingException e) {
					e.printStackTrace();
					mHandler.sendEmptyMessage(SHOW_FAILURE);
					mHandler.sendEmptyMessage(CONTENT_STATUS);
				} catch (ClientProtocolException e) {
					e.printStackTrace();
					mHandler.sendEmptyMessage(SHOW_FAILURE);
					mHandler.sendEmptyMessage(CONTENT_STATUS);
				} catch (SocketException e) {
					mHandler.sendEmptyMessage(SHOW_FAILURE);
					mHandler.sendEmptyMessage(CONTENT_STATUS);
				} catch (IOException e) {
					mHandler.sendEmptyMessage(SHOW_FAILURE);
					mHandler.sendEmptyMessage(CONTENT_STATUS);
					e.printStackTrace();
				} catch (JSONException e) {
					mHandler.sendEmptyMessage(SHOW_FAILURE);
					mHandler.sendEmptyMessage(CONTENT_STATUS);
					e.printStackTrace();
				}
			}
		}).start();
	}


3.xUtils框架的post上傳資料,表單格式

/**
	 * 表單格式傳送(鍵值對)
	 */
	private void xUtilsFrame() {
		RequestParams params = new RequestParams();
		params.addBodyParameter("romversion", serviceInfoMap.get("romversion"));
		params.addBodyParameter("brand", serviceInfoMap.get("brand"));
		params.addBodyParameter("model", serviceInfoMap.get("model"));
		params.addBodyParameter("device", serviceInfoMap.get("device"));
		params.addBodyParameter("imei", serviceInfoMap.get("imei"));
		Log.i(TEST_TAG, params.getEntity().toString());

		HttpUtils http = new HttpUtils();
		http.configCurrentHttpCacheExpiry(1000 * 10);
		http.send(HttpMethod.POST, ACTIVATE_PATH, params,
				new RequestCallBack<String>() {

					@Override
					public void onSuccess(ResponseInfo<String> responseInfo) {
						Log.i(TEST_TAG, "接收到的結果為---》" + responseInfo.result);
						Log.i(TEST_TAG, "請求碼為--->" + responseInfo.statusCode);
						try {
							JSONObject jsonObject = new JSONObject(
									responseInfo.result);
							Log.i(TEST_TAG, jsonObject.getString("message"));
							if (jsonObject.getString("status").equals("1")) {
								mHandler.sendEmptyMessage(CLOSE_DIALOG);
								mHandler.sendEmptyMessage(SHOW_SUCCESS);
								Settings.System.putInt(getContentResolver(),
										SETTING_MODIFY_NAME, 1);
							} else {
								mHandler.sendEmptyMessage(CLOSE_DIALOG);
								mHandler.sendEmptyMessage(SHOW_FAILURE);
							}
						} catch (JSONException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}

					@Override
					public void onFailure(HttpException error, String msg) {
						Toast.makeText(getApplicationContext(), "失敗了",
								Toast.LENGTH_LONG).show();
					}
				});
	}

4.xUtils框架,json資料格式

/**
	 * 傳送json字串
	 */
	private void xUtilsFrame2() {
		try {
			RequestParams params = new RequestParams();
			// 先封裝一個JSON物件
			JSONObject param = new JSONObject();
			param.put("romversion", serviceInfoMap.get("romversion"));
			param.put("brand", serviceInfoMap.get("brand"));
			param.put("model", serviceInfoMap.get("model"));
			param.put("device", serviceInfoMap.get("device"));
			param.put("imei", serviceInfoMap.get("imei"));
			StringEntity sEntity = new StringEntity(param.toString(), "utf-8");
			params.setBodyEntity(sEntity);
			Log.i(TEST_TAG, "params-->" + params.toString()); // params-->[email protected]
			Log.i(TEST_TAG, "param-->" + param.toString()); // param-->{"device":"hwG620S-UL00","brand":"HUAWEI","model":"G620S-UL00","imei":"865242024756522","romversion":"G620S-UL00V100R001C17B264"}
			Log.i(TEST_TAG, "param-entity-->" + sEntity.toString()); // param-entity-->[email protected]

			HttpUtils http = new HttpUtils();
			http.configCurrentHttpCacheExpiry(1000 * 10);
			http.send(HttpMethod.POST, ACTIVATE_PATH, params,
					new RequestCallBack<String>() {

						@Override
						public void onSuccess(ResponseInfo<String> responseInfo) {
							Log.i(TEST_TAG, "接收到的結果為---》" + responseInfo.result); // 接收到的結果為---》{"status":"2","datatime":1437444596,"message":"引數無效!"}
							Log.i(TEST_TAG, "請求碼為--->"
									+ responseInfo.statusCode);
							try {
								JSONObject jsonObject = new JSONObject(
										responseInfo.result);
								Log.i(TEST_TAG, jsonObject.getString("message"));
								if (jsonObject.getString("status").equals("1")) {
									mHandler.sendEmptyMessage(CLOSE_DIALOG);
									mHandler.sendEmptyMessage(SHOW_SUCCESS);
									Settings.System.putInt(
											getContentResolver(),
											SETTING_MODIFY_NAME, 1);
								} else {
									mHandler.sendEmptyMessage(CLOSE_DIALOG);
									mHandler.sendEmptyMessage(SHOW_FAILURE);
								}
							} catch (JSONException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
						}

						@Override
						public void onFailure(HttpException error, String msg) {
							Toast.makeText(getApplicationContext(), "失敗了",
									Toast.LENGTH_LONG).show();
						}
					});

		} catch (JSONException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

5.Volley框架:StringRequest,from表單

/**
	 * Volley框架:StirngRequest(需要匯入Volley.jar包到libs目錄下,需要加internet許可權)
	 */
	private void volleyFrameSR() {
		// 第一步:建立一個RequestQueue物件
		final RequestQueue mQueue = Volley.newRequestQueue(this);
		// 第二步:建立一個StringRequest物件
		StringRequest stringRequest = new StringRequest(Method.POST,
				ACTIVATE_PATH, new Response.Listener<String>() {
					// 伺服器響應成功的回撥
					@Override
					public void onResponse(String response) {
						Log.i(TEST_TAG, "返回結果為--->" + response);
						try {
							JSONObject jsonObject = new JSONObject(response);
							Log.i(TEST_TAG,
									"status-->"
											+ jsonObject.getString("status"));
							Log.i(TEST_TAG,
									"message-->"
											+ jsonObject.getString("message"));
							mQueue.cancelAll("StringRequest");
							mHandler.sendEmptyMessage(SHOW_SUCCESS);
							mHandler.sendEmptyMessage(CLOSE_DIALOG);
						} catch (JSONException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}

				}, new Response.ErrorListener() {
					// 伺服器響應失敗的回撥
					@Override
					public void onErrorResponse(VolleyError error) {
						Log.e(TEST_TAG, error.getMessage(), error);
						mHandler.sendEmptyMessage(SHOW_FAILURE);
					}
				}) {

			@Override
			protected Map<String, String> getParams() throws AuthFailureError {
				Map<String, String> map = new HashMap<String, String>();
				map.put("romversion", serviceInfoMap.get("romversion"));
				map.put("brand", serviceInfoMap.get("brand"));
				map.put("model", serviceInfoMap.get("model"));
				map.put("device", serviceInfoMap.get("device"));
				map.put("imei", serviceInfoMap.get("imei"));
				Log.i(TEST_TAG, "傳送結果為--->" + map.toString());
				// 傳送結果為--->{device=hwG620S-UL00, brand=HUAWEI,
				// model=G620S-UL00, imei=865242024756522,
				// romversion=G620S-UL00V100R001C17B264}

				return map;
			}
		};
		stringRequest.setTag("StringRequest");
		// 第三步:將StringRequest物件新增到RequestQueue裡面
		mQueue.add(stringRequest);
	}
這個寫了太多的程式碼,這是方法的原型:
StringRequest stringRequest = new StringRequest(Method.POST, url,  listener, errorListener) {  
    @Override  
    protected Map<String, String> getParams() throws AuthFailureError {  
        Map<String, String> map = new HashMap<String, String>();  
        map.put("params1", "value1");  
        map.put("params2", "value2");  
        return map;  
    }  
};  
根據我伺服器的接受模式,我覺得他傳送的結果是form表單格式

6.Volley框架: JsonObjectRequest。 

因為它的方法中傳遞的的請求引數為JsonObject,目前還沒有找到傳遞form格式的方法。

/**
	 * Volley框架:JsonObjectRequest
	 */
	private void volleyFrameJR() {
		// 第一步:建立一個RequestQueue物件
		final RequestQueue mQueue = Volley.newRequestQueue(this);

		JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(
				Method.POST, ACTIVATE_PATH, null,
				new Response.Listener<JSONObject>() {

					@Override
					public void onResponse(JSONObject response) {
						Log.i(TEST_TAG, "返回結果為--->" + response.toString());
						try {
							// JSONObject jsonObject = new JSONObject(response);
							Log.i(TEST_TAG,
									"status-->" + response.getString("status"));
							Log.i(TEST_TAG,
									"message-->"
											+ response.getString("message"));
							mHandler.sendEmptyMessage(SHOW_SUCCESS);
							mHandler.sendEmptyMessage(CLOSE_DIALOG);
						} catch (JSONException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}, new Response.ErrorListener() {

					@Override
					public void onErrorResponse(VolleyError error) {
						Log.e(TEST_TAG, error.getMessage(), error);
						mHandler.sendEmptyMessage(SHOW_FAILURE);
					}
				}) {
			
			@Override
			protected Map<String, String> getPostParams()
					throws AuthFailureError {
				Map<String, String> map = new HashMap<String, String>();
				map.put("romversion", serviceInfoMap.get("romversion"));
				map.put("brand", serviceInfoMap.get("brand"));
				map.put("model", serviceInfoMap.get("model"));
				map.put("device", serviceInfoMap.get("device"));
				map.put("imei", serviceInfoMap.get("imei"));
				Log.i(TEST_TAG, "傳送結果為--->" + map.toString());
				return map;
			}

		};
		mQueue.add(jsonObjectRequest); // 沒有這句就無法互動

	}
這種方式應該可以,好像getParams也可以,因為伺服器寫的不是接受json格式資料,所以我沒法測試。

還有就是去掉重寫的方法,不管是getPostParams還是getParams,然後將裡面的map集合內容寫道,new JsonObjectRequest之前,然後在JsonObject  jsonObject = newJsonObject(map),然後將jsonObject作為第三個引數,這樣就傳遞了一個json字串到伺服器。

7.JsonObject和JsonArray

//JsonObject和JsonArray區別就是JsonObject是物件形式,JsonArray是陣列形式
        //建立JsonObject第一種方法
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("UserName", "ZHULI");
        jsonObject.put("age", "30");
        jsonObject.put("workIn", "ALI");
        System.out.println("jsonObject1:" + jsonObject);
        
        //建立JsonObject第二種方法
        HashMap<String, String> hashMap = new HashMap<String, String>();
        hashMap.put("UserName", "ZHULI");
        hashMap.put("age", "30");
        hashMap.put("workIn", "ALI");
        System.out.println("jsonObject2:" + JSONObject.fromObject(hashMap));
        
        //建立一個JsonArray方法1
        JSONArray jsonArray = new JSONArray();
        jsonArray.add(0, "ZHULI");
        jsonArray.add(1, "30");
        jsonArray.add(2, "ALI");
        System.out.println("jsonArray1:" + jsonArray);
        
        //建立JsonArray方法2
        ArrayList<String> arrayList = new ArrayList<String>();
        arrayList.add("ZHULI");
        arrayList.add("30");
        arrayList.add("ALI");
        System.out.println("jsonArray2:" + JSONArray.fromObject(arrayList));
        
        //如果JSONArray解析一個HashMap,則會將整個物件的放進一個數組的值中
        System.out.println("jsonArray FROM HASHMAP:" + JSONArray.fromObject(hashMap));
        
        //組裝一個複雜的JSONArray
        JSONObject jsonObject2 = new JSONObject();
        jsonObject2.put("UserName", "ZHULI");
        jsonObject2.put("age", "30");
        jsonObject2.put("workIn", "ALI");
        jsonObject2.element("Array", arrayList);
        System.out.println("jsonObject2:" + jsonObject2);

system結果:
jsonObject1:{"UserName":"ZHULI","age":"30","workIn":"ALI"}
jsonObject2:{"workIn":"ALI","age":"30","UserName":"ZHULI"}
jsonArray1:["ZHULI","30","ALI"]
jsonArray2:["ZHULI","30","ALI"]
jsonArray FROM HASHMAP:[{"workIn":"ALI","age":"30","UserName":"ZHULI"}]
jsonObject2:{"UserName":"ZHULI","age":"30","workIn":"ALI","Array":["ZHULI","30","ALI"]}
</pre><pre name="code" class="html" style="font-size: 13px; margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; line-height: 19.5px; background-color: rgb(254, 254, 242);">
<span style="font-size:24px;">android讀取json資料(遍歷JSONObject和JSONArray)</span>
<pre name="code" class="java">public String getJson(){  
        String jsonString = "{\"FLAG\":\"flag\",\"MESSAGE\":\"SUCCESS\",\"name\":[{\"name\":\"jack\"},{\"name\":\"lucy\"}]}";//json字串  
        try {  
            JSONObject result = new JSONObject(jsonstring);//轉換為JSONObject  
            int num = result.length();  
            JSONArray nameList = result.getJSONArray("name");//獲取JSONArray  
            int length = nameList.length();  
            String aa = "";  
            for(int i = 0; i < length; i++){//遍歷JSONArray  
                Log.d("debugTest",Integer.toString(i));  
                JSONObject oj = nameList.getJSONObject(i);  
                aa = aa + oj.getString("name")+"|";  
                  
            }  
            Iterator<?> it = result.keys();  
            String aa2 = "";  
            String bb2 = null;  
            while(it.hasNext()){//遍歷JSONObject  
                bb2 = (String) it.next().toString();  
                aa2 = aa2 + result.getString(bb2);  
                  
            }  
            return aa;  
        } catch (JSONException e) {  
            throw new RuntimeException(e);  
        }  
    }  


8.生成陣列json串

我想要生成的json串為: {
"languages": [//應用市場所支援的語種資訊
  {
"name":"漢語",
"code":"hy",
"selected":"true"
  },
  {
"name":"蒙古語",
"code":"mn"
"selected":"false"
  }
],
"applist_versioncode":"0",
"applist_num":"2", }
程式碼如下:
private void createJsonData() {
		try {
			// 存放總的json資料的容器
			JSONObject jsonObject = new JSONObject();

			/*
			 * 首先,總的josn的第一條的key是languages,他的value是一個數組,陣列有兩個元素,所以,
			 * languages對應的value是一個JsonArray物件
			 */
			// 此時生成一個jsonarray來存放language的值的陣列
			JSONArray jsonArrayLang = new JSONArray();
			// 首先將language的第一條資料,生成jsonObject物件
			JSONObject joLang0 = new JSONObject();
			joLang0.put("name", "漢語");
			joLang0.put("code", "hy");
			joLang0.put("selected", "true");
			// 此時,將陣列的第一組資料新增到jsonarray中
			jsonArrayLang.put(0, joLang0);

			// 首先將language的第二條資料,生成jsonObject物件
			JSONObject joLang1 = new JSONObject();
			joLang1.put("name", "蒙古語");
			joLang1.put("code", "mn");
			joLang1.put("selected", "false");
			// 此時,將陣列的第一組資料新增到jsonarray中
			jsonArrayLang.put(1, joLang1);

			// 此時,langauge的值已經生成,就是jsonarraylang這個陣列格式的資料
			// 然後,將其新增到總的jsonobject中
			jsonObject.put("languages", jsonArrayLang);
			// 新增總jsonobject容器的第二條資料,"applist_versioncode":"0",
			jsonObject.put("applist_versioncode", "0");
			// 新增總jsonobject容器的第三條資料,"applist_num":"2",
			jsonObject.put("applist_num", "2");

			System.out.println(jsonObject.toString());

		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
最後輸出結果為

9.修改json串(帶陣列)

String stt = "{\"languages\":[{\"name\":\"漢語\",\"code\":\"hy\"},"
			+ "{\"name\":\"蒙古語\",\"code\":\"mn\"}]}";
<span style="white-space:pre">				</span>try {
					JSONObject jsonObject = new JSONObject(stt);
					System.out.println("修改之前---->" + jsonObject.toString());
					JSONArray jsonArray = jsonObject.getJSONArray("languages");
					System.out.println("修改之前---->" + jsonArray.toString());
					System.out.println("jsonArray.length()---->"
							+ jsonArray.length());
					for (int i = 0; i < jsonArray.length(); i++) {
						JSONObject jsonObject2 = (JSONObject) jsonArray.opt(i);
						System.out.println("jsonObject2---->" + i + "-----"
								+ jsonArray.toString());
						if (i == (jsonArray.length() - 1)) {
							System.out.println("修改之前---->");
							jsonObject2.put("name", "法國與");
							jsonArray.put(i, jsonObject2);
						}
					}
					jsonArray.put(jsonArray.length(),
							(JSONObject) jsonArray.opt(jsonArray.length() - 1));
					jsonObject.put("languages", jsonArray);
					System.out.println("修改之後---->" + jsonObject.toString());
				} catch (JSONException e) {
					e.printStackTrace();
				}
修改json串,就需要一層一層讀出來,然後key值存在的時候,直接put新值,就會直接替換掉,然後在一層一層添加回去。這樣就可以了

10.Gson解析

首先需要在build.gradle中新增gson依賴

    compile 'com.google.code.gson:gson:2.8.0'
GsonUtils.java
package njj.com.myapplication1;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.List;

/**
 * Created by jian on 2016/12/21.
 */
public class GsonUtils {

    static String response1 = "{\"name\":\"niejian\",\"age\":\"24\"}";
    static String response2 = "{\"bean\":[{\"name\":\"niejian\",\"age\":\"24\"},{\"name\":\"xiaonie\",\"age\":\"20\"},{\"name\":\"xiaojian\",\"age\":\"30\"}]}";

    /**
     * 解析單條資料
     * @return
     */
    public static Bean singleGetResponse() {
//      response1 = {"name":"niejian","age":"24"}
        Gson gson = new Gson();
        Bean bean = gson.fromJson(response1, Bean.class);
        return bean;
    }

    /**
     * 解析多條資料
     * @return
     */
    public static List<Bean> getResponse() {
//      response2 = {"bean":[{"name":"niejian","age":"24"},{"name":"xiaonie","age":"20"},{"name":"xiaojian","age":"30"}]}
        List<Bean> beans = null;
        try {
            JSONObject jsonObject = new JSONObject(response2);
            JSONArray jsonArray = jsonObject.getJSONArray("bean");
            Gson gson = new Gson();
            // jsonArray.toString = [{"name":"niejian","age":"24"},{"name":"xiaonie","age":"20"},{"name":"xiaojian","age":"30"}]
            // 引數一傳入陣列
            beans = gson.fromJson(jsonArray.toString(), new TypeToken<List<Bean>>() {
            }.getType());

        } catch (JSONException e) {
            e.printStackTrace();
        }
        return beans;
    }

}

class Bean {
    /**
     * name : niejian
     * age : 24
     */

    private String name;
    private String age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
}
 使用方法:
                Bean bean = GsonUtils.singleGetResponse();
                String name = bean.getName();
                String age = bean.getAge();
                Log.i("niejianjian", "neme : " + name + "; age = " + age);

                List<Bean> beanList = GsonUtils.getResponse();
                for (Bean bean1 : beanList){
                    Log.i("niejianjian", "neme : " + bean1.getName() + "; age = " + bean1.getAge());
                }
就這麼簡單!!!



參考部落格:



相關推薦

android伺服器互動總結jsonpostxUtilsVolleyGson

(最後一次更新2016 - 12 - 21) 更新內容:由於android 6.0完全拋棄了HttpClinet,所以,原生的網路請求,建議使用HttpURLConnection,本文的第三方框架,都是去年比較老的,現在xutils都更新到xutils3了,沒有大檔案的網

瀏覽器伺服器互動資訊序列化發序列化 ViewState

本篇來解釋上篇博文中使用者輸入資料沒有消失的問題。(由於http協議的無狀態性使得每次頁面請求都會重新建立所有控制元件。即所有的資料都將不復存在) 先來看一下asp.net頁面的生命週期 ASP.NET頁面的生命週期:(詳見ASP.Net4.0權威指南第1章第3節) 1.瀏

AndroidAndroid伺服器互動 POST上傳多個圖片檔案、文字內容 GET下載圖片

這裡伺服器端採用的是php解析內容 HTTP請求   HTTP 請求方法有 OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE、CONNECT 這幾種。用於資料互動的最基本方法一般為GET、POST、PUT、DELETE。對

HTTP伺服器互動的方式get和post的區別

1.http四種互動方式: get和post是HTTP與伺服器互動的方式,  說到方式,其實總共有四種:put,delete,post,get。  他們的作用分別是對伺服器資源的增,刪,改,查。  所以,get是獲取資料,post是修改資料。 2.

AndroidJavaWeb伺服器互動教程3-一個簡單的Android專案

1.前言 是時候該寫Android端了。。。 2.建立專案 3.匯入xUtils3框架 送上xUtil3框架的傳送門 附上jar包的下載地址: 百度雲 七牛雲 以及json的下載地址 七牛雲 百度雲 把jar包拷入libs

Android程式伺服器互動

在公司一個專案中用到了這樣一種網路請求方式,在此記錄學習。 1.java程式碼 /** * 訪問網路改變座位號 */ private void saveSeatNumber() { Controller.g

Android實現登入功能Android伺服器資料互動使用tomcat、mysql實現登入的demo程式web端和android均可實現登入

1.使用到的開發工具為:Eclipse(Java EE),Android Studio,MYSQL 5.7.21;2.首先在MYSQL資料庫建表,我這裡使用的資料庫視覺化操作軟體為:navicat premium:如圖:這裡你可以取自己喜歡的資料庫名字,但是為了方便起見,我建

【中期檢查】 搭建Android伺服器瀏覽器互動總結

最近在寫優麒麟手機助手這個專案,優麒麟手機助手是Ubuntu Kylin組織的開源專案: 在Windows平臺上有眾多的安卓手機管理工具,如360手機助手、騰訊手機管家、豌豆莢等,但是在Linux平臺下卻鮮有功能強大的客戶端出現。為了一解我等Linuxer在學習

Android使用https伺服器互動的正確姿勢

HTTPS 使用 SSL 在客戶端和伺服器之間進行加密通訊,錯誤地使用 SSL ,將會導致其它人能夠攔截網路上的應用資料。 使用一個包含公鑰及與其匹配的私鑰的證書配置伺服器,作為 SSL 客戶端與伺服器握手的一部分,伺服器將通過使用公鑰加密簽署其證書來證明自己具有私鑰。 主機平臺一般包含其信任的知名 CA

安卓混淆之後androidjs互動異常原因

解決方案:需要js互動程式碼不被混淆掉,加入以下程式碼即可 -keepclassmembers class com.taohaohuo365.taohaohuo.activity.H5Activity$AndroidAndJSInterface { public *; } -keepcla

jsonjsonp區別淺析json才是目的jsonp只是手段

一言以蔽之,json返回的是一串資料;而jsonp返回的是指令碼程式碼(包含一個函式呼叫); JSON其實就是JavaScript中的一個物件,跟var obj={}在質上完全一樣,只是在量上可以無限擴充套件。簡單地講,json其實就是JavaScript中的物件(Obj

Android通知欄介紹適配總結上篇

此文已由作者黎星授權網易雲社群釋出。 歡迎訪問網易雲社群,瞭解更多網易技術產品運營經驗。 由於歷史原因,Android在釋出之初對通知欄Notification的設計相當簡單,而如今面對各式各樣的通知欄玩法,谷歌也不得不對其進行更新迭代調整,增加新功能的同時,也在不斷地改變樣式,試圖迎合更多

android:RecyclerView互動動畫上下拖動左右滑動刪除

效果 RecyclerView互動動畫主要使用的是ItemTouchHelper這個類 建立MyItemTouchHelperCallback繼承系統ItemTouchHelper.Callback import android.graphi

Web頁面通過MQTT協議伺服器互動Mosca安裝測試

在伺服器上安裝node的執行環境和mosca庫 yum install nodejs yum install zeromq-devel mkdir devel cd devel npm install --save mosca node mqttserver.j

Androidjs互動帶進度條的載入H5頁面

private void initWebView() { WebSettings settings = wvResumeDetail.getSettings(); //支援JavaScript指令碼語言 settings

Android自定義View總結基礎知識例項

自定義View是最能體現一個Android開發者水平的技能之一了。 接下來的一些列部落格將總結一下Android的自定義相關View知識,包括View的結構,事件體系,工作原理,自定義View的繪製等。 參考資料部分來自於書上以及各種部落格。 新建了一個qq群 482

Android伺服器端通訊方式之HTTP、TCP、Socket

      Android作為客戶端,與伺服器的通訊方式主要有兩種:一種是HTTP通訊,一種是Socket通訊。 一、HTTP、Socket簡介       HTTP通訊:即使用HTTP協議進行通訊,工作原理是客戶端向伺服器端傳送一條HTTP請求,伺服器收到之後先解析客戶

Android開發學習——android伺服器端資料互動

public class MainActivity extends Activity { private ListView lv; private List<Food> data = new ArrayList<Food>(); pr

簡化AndroidJS互動JsBridge框架全面解析

今日科技快訊近日,滴滴順風車披露了一組數字,預測春運前後,跨城出行以7天為一個週期,呈“潮汐式”

Androidjs互動自定義cordova外掛

首先昨天我做測試的時候js端一直無法呼叫寫在js的方法後來查了資料才知道是在index.html中使用js時 需要刪除這一行 <meta http-equiv="Content-Security-Policy" content="default-src 'self'