編輯:關於Android編程
上節我們把簡單的項目搭起來了,然後把倉庫托管到Github上了,經過分析,
我們覺得有必要把下面兩點優化下:
1.URL寫死 -> 解析接口返回的Json,處理獲取圖片URL
2.優化圖片加載,添加本地加載
本節就來完成上述的第一點!
1)在Develop上開辟功能分支:parse_json
2)摳腳Json解析接口數據<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPsr9vt3AtNS0vdO/2qO6PGEgaHJlZj0="http://gank.io/api">Gank.io API
這裡我們用的是接口是:http://gank.io/api/data/福利/{請求個數}/{第幾頁}
例如:每頁顯示10個,第一頁:http://gank.io/api/data/福利/10/1
先看下服務器返回的Json格式:
PS:格式化Json的是Chrome的插件:JSON_handle
根據這個我們先來編寫我們的Bean類:Sister.java:
/** * 描述:妹子業務Bean * * @author coder-pig: 2016/08/06 17:16 */ public class Sister { private String _id; private String createAt; private String desc; private String publishedAt; private String source; private String type; private String url; private boolean used; private String who; // 一些get和set方法... }
接下來我們編寫一個用來解析網絡數據的類,這個類裡要做的事依次是:
Step 1:通過HttpUrlConnection發起Get請求,然後獲得後台返回的數據,此時是流形式的 Step 2:我們需要寫一個流轉成字節數組的方法 Step 3:將字節數組轉成字符串後,得到的就是後台的給我們返回的數據了,接著要做的就
是寫一個解析這一大串Json的方法了,我們需要獲取Json裡我們需要的數據,丟到Bean裡 Step 4:返回處理後的集合數據
於是乎我們編寫一個網絡請求的處理類:SisterApi.java:
/** * 描述:網絡請求處理相關類 * * @author coder-pig: 2016/08/07 14:28 */ public class SisterApi { private static final String TAG = "Network"; private static final String BASE_URL = "http://gank.io/api/data/福利/"; /** * 查詢妹子信息 */ public ArrayListfetchSister(int count, int page) { String fetchUrl = BASE_URL + count + "/" + page; ArrayList sisters = new ArrayList<>(); try { URL url = new URL(fetchUrl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(5000); conn.setRequestMethod("GET"); int code = conn.getResponseCode(); Log.v(TAG, "Server response:" + code); if (code == 200) { InputStream in = conn.getInputStream(); byte[] data = readFromStream(in); String result = new String(data, "UTF-8"); sisters = parseSister(result); } else { Log.e(TAG,"請求失敗:" + code); } } catch (Exception e) { e.printStackTrace(); } return sisters; } /** * 解析返回Json數據的方法 */ public ArrayList parseSister(String content) throws Exception { ArrayList sisters = new ArrayList<>(); JSONObject object = new JSONObject(content); JSONArray array = object.getJSONArray("results"); for (int i = 0; i < array.length(); i++) { JSONObject results = (JSONObject) array.get(i); Sister sister = new Sister(); sister.set_id(results.getString("_id")); sister.setCreateAt(results.getString("createdAt")); sister.setDesc(results.getString("desc")); sister.setPublishedAt(results.getString("publishedAt")); sister.setSource(results.getString("source")); sister.setType(results.getString("type")); sister.setUrl(results.getString("url")); sister.setUsed(results.getBoolean("used")); sister.setWho(results.getString("who")); sisters.add(sister); } return sisters; } /** * 讀取流中數據的方法 */ public byte[] readFromStream(InputStream inputStream) throws Exception { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len ; while ((len = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, len); } inputStream.close(); return outputStream.toByteArray(); } }
好的,接著我們就去調用這個網絡請求類了,我們把調用寫在MainActivity.java裡
而Android是不允許在主線程做網絡操作的這裡我們就不直接new Runnable,
直接寫一個AsyncTask,在裡面進網絡操作,還有一些簡單的邏輯。
public class MainActivity extends AppCompatActivity implements View.OnClickListener { private Button showBtn; private Button refreshBtn; private ImageView showImg; private ArrayListdata; private int curPos = 0; //當前顯示的是哪一張 private int page = 1; //當前頁數 private PictureLoader loader; private SisterApi sisterApi; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sisterApi = new SisterApi(); loader = new PictureLoader(); initData(); initUI(); } private void initData() { data = new ArrayList<>(); new SisterTask(page).execute(); } private void initUI() { showBtn = (Button) findViewById(R.id.btn_show); refreshBtn = (Button) findViewById(R.id.btn_refresh); showImg = (ImageView) findViewById(R.id.img_show); showBtn.setOnClickListener(this); refreshBtn.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_show: if(data != null && !data.isEmpty()) { if (curPos > 9) { curPos = 0; } loader.load(showImg, data.get(curPos).getUrl()); curPos++; } break; case R.id.btn_refresh: page++; new SisterTask(page).execute(); curPos = 0; break; } } private class SisterTask extends AsyncTask > { private int page; public SisterTask(int page) { this.page = page; } @Override protected ArrayList doInBackground(Void... params) { return sisterApi.fetchSister(10,page); } @Override protected void onPostExecute(ArrayList sisters) { super.onPostExecute(sisters); data.clear(); data.addAll(sisters); } } }
核心是這些,還有一些小改動,加了個Application的類,調整了一下結構,變成這樣的:
依次鍵入命令提交代碼:
提交完到Github上可以看到:
因為沒下載Github客戶端,所以分支合並就用命令行走一發了:
切到develop分支上,走一波merge parse_json
然後把合並後的develop提交到Github,(因為一個人開發,所以基本不用處理沖突
好的,推完看到github上的develop內容已經發生了變化
那麼開辟的這個parse_json分支,現在已經沒什麼作用了,我們可以用命令刪掉這個分支:
當然,這裡我們刪除的只是本地倉庫,Github上還是有這個分支的,再鍵入命令:
然後到GitHub上面看看:
好的,分支已經被刪除了!develop分支上的代碼也是最新的代碼了!
源碼下載:DrySister
AndroidProgressLayout實現為界面添加圓形進度條。調用setprogress()方法顯示和隱藏進度條在Android的開發中,往往有這種需求,比如一個耗
之前一篇文章,介紹了如何定義從屏幕底部彈出PopupWindow即《Android Animation實戰之屏幕底部彈出PopupWindow》,寫完之後,突然想起之前寫
這篇博客我們來介紹一下建造者模式(Builder Pattern),建造者模式又被稱為生成器模式,是創造性模式之一,與工廠方法模式和抽象工廠模式不同,後兩者的目的是為了實
通常也稱作套接字,用於描述IP地址和端口,是一個通信鏈的句柄。在Internet上的主機一般運行了多個服務軟件,同時提供幾種服務。每種服務都打開一個Socket,並綁定