##Android基礎網絡第一天html
訪問網絡須要加Internet權限: android.permission.INTERNET 使用UrlConnection請求一個url地址獲取內容: //1.建立一個Url對象 URL url = new URL(url_str); //2.獲取一個UrlConnection對象 HttpURLConnection connection = (HttpURLConnection)url.openConnection(); //3.爲UrlConnection對象設置一些請求的參數,請求方式,鏈接的超時時間 connection.setRequestMethod("GET");//設置請求方式 connection.setConnectTimeout(1000*10);//設置超時時間 //4.在獲取url請求的數據前須要判斷響應碼,200 :成功,206:訪問部分數據成功 300:跳轉或重定向 400:錯誤 500:服務器異常 int code = connection.getResponseCode(); if(code == 200){ //5.獲取有效數據,並將獲取的流數據解析成String InputStream inputStream = connection.getInputStream(); String result = StreamUtils.streamToString(inputStream); 注意事項: 1. ANR:application not response 應用無響應; androoid中耗時的操做(請求網絡,大文件的拷貝,數據庫的操做)須要在子線程中作。 09-02 01:52:40.711: E/ActivityManager(857): ANR in com.itheima.sourcelook (com.itheima.sourcelook/.MainActivity) 2. 4.0後網絡操做強制在子線程中進行。由於網絡訪問是耗時的操做,可能會致使ANR 09-02 01:57:32.879: W/System.err(1789): android.os.NetworkOnMainThreadException 3.錯誤線程調用異常,子線程不可以更新UI(控件的內容) 09-02 02:02:08.873: W/System.err(1858): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 主線程不可以作耗時的操做,網絡請求就是耗時的操做須要放到子線程作。子線程不能更新控件的內容(更新Ui)。因此產生了矛盾,解決辦法就是使用Handler.
使用Handler的步驟: 1.主線程中建立一個Handler private Handler handler = new Handler(){ public void handleMessage(android.os.Message msg) { }; }; 2.重寫handler的handlermessage方法 3.子線程中建立一個Message對象,將獲取的數據綁定給msg Message msg = new Message(); //另外一種方式:Message msg = Messge.obtain; msg.obj = result; 4.主線程中的handler對象在子線程中將message發送給主線程 handler.sendMessage(msg); 5.主線程中handlermessage方法接受子線程發來的數據,就能夠作更新UI的操做。 ***********主線程 //☆☆☆1.在主線程中建立一個Handler對象 private Handler handler = new Handler(){ //☆☆☆2.重寫handler的handlermessage方法,用來接收子線程中發來的消息 public void handleMessage(android.os.Message msg) { //☆☆☆5.接收子線程發送的數據,處理數據。 Bitmap bitmap = (Bitmap) msg.obj; //☆☆☆6.當前方法屬於主線程能夠作UI的更新 //五.獲取服務器返回的內容,顯示到textview上 img_pic.setImageBitmap(bitmap);//設置ImageView的圖片內容 }; }; ************子線程 if(code == 200){ //5.獲取有效數據,並將獲取的流數據解析成String InputStream inputStream = connection.getInputStream(); //將一個讀取流轉換成一個圖片 Drawable , Btimap:位圖 ????? Bitmap bitmap = BitmapFactory.decodeStream(inputStream); //☆☆☆3.子線中建立一個Message對象,爲了攜帶子線程中獲取的數據給主線程。 Message msg = Message.obtain();//獲取一個Message對象,內部實現是:若是以前的Message存在直接返回,不存在建立新的Message返回 msg.obj = bitmap;//將獲取的數據封裝到msg中。 //☆☆☆4.使用handler對象將message發送到主線程。 handler.sendMessage(msg); }
有幾個主要元素: 1.Message:用來攜帶子線程中的數據。 2.MessageQueue:用來存放全部子線程發來的Message. 3.Handler:用來在子線程中發送Message,在主線程中接受Message,處理結果 4.Looper:是一個消息循環器,一直循環遍歷MessageQueue,從MessageQueue中取一個Message,派發給Handler處理。 原理看資料中的圖。
adb shell+ input text 內容;能夠經過將內容輸入到手機上的輸入框。 將一個讀取流轉換成bitmap對象: BitmapFactory:能夠將文件,讀取流,字節數組轉換成一個Bitmap對象。 Bitmap bitmap = BitmapFactory.decodeStream(InputStream in); imageView.setImageBitmap(bitmap);//設置圖片內容
面試:子線程必定不能更新UI? SurfaceView :多媒體視頻播放 ,能夠在子線程中更新UI; Progress(進度)相關的控件:也是能夠在子線程中更新Ui;審計機制:activity徹底顯示的時候審計機制纔會去檢測子線程有沒有更新Ui. 1.使用activity的runOnUiThread方法更新ui,不管當前線程是不是主線程,都將在主線程執行. runOnUiThread(new Runnable() { [@Override](https://my.oschina.net/u/1162528) public void run() { tv_simple.setText("我被更新了"); } }); 2.使用handler直接post到主線程,handler須要在主線程建立 //延遲多少毫米執行runnable。 mHandler.postDelayed(new Runnable() { [@Override](https://my.oschina.net/u/1162528) public void run() { tv_simple.setText("我被更新了"); } }, 1000*5); 應用場景:廣告展現後,作頁面跳轉。
第一次進入新聞客戶端須要請求服務器獲取新聞數據,作listview的展現,爲了第二次再次打開新聞客戶端時能快速顯示新聞,須要將數據緩存到數據庫中,下次打開能夠直接去數據庫中獲取新聞直接作展現。 1.寫佈局listview ok 2.找到listview,設置條目的點擊事件。 ok 3.獲取數據提供給listview作展現。 3.1:獲取本地數據庫緩存的新聞數據,讓listview顯示。若是沒有網絡不至於顯示空界面。 3.2:請求服務器獲取新聞數據,是一個json字符串,須要解析json,封裝到list集合中。提供給listview展現。 public static String newsPath_url = "http://192.168.13.83:8080/itheima74/servlet/GetNewsServlet"; //封裝新聞的假數據到list中返回 public static ArrayList<NewsBean> getAllNewsForNetWork(Context context) { ArrayList<NewsBean> arrayList = new ArrayList<NewsBean>(); try{ //1.請求服務器獲取新聞數據 //獲取一個url對象,經過url對象獲得一個urlconnnection對象 URL url = new URL(newsPath_url); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); //設置鏈接的方式和超時時間 connection.setRequestMethod("GET"); connection.setConnectTimeout(10*1000); //獲取請求響應碼 int code = connection.getResponseCode(); if(code == 200){ //獲取請求到的流信息 InputStream inputStream = connection.getInputStream(); String result = StreamUtils.streamToString(inputStream); //2.解析獲取的新聞數據到List集合中。 JSONObject root_json = new JSONObject(result);//將一個字符串封裝成一個json對象。 JSONArray jsonArray = root_json.getJSONArray("newss");//獲取root_json中的newss做爲jsonArray對象 for (int i = 0 ;i < jsonArray.length();i++){//循環遍歷jsonArray JSONObject news_json = jsonArray.getJSONObject(i);//獲取一條新聞的json NewsBean newsBean = new NewsBean(); newsBean. id = news_json.getInt("id"); newsBean. comment = news_json.getInt("comment");//評論數 newsBean. type = news_json.getInt("type");//新聞的類型,0 :頭條 1 :娛樂 2.體育 newsBean. time = news_json.getString("time"); newsBean. des = news_json.getString("des"); newsBean. title = news_json.getString("title"); newsBean. news_url = news_json.getString("news_url"); newsBean. icon_url = news_json.getString("icon_url"); arrayList.add(newsBean); } //3.清楚數據庫中舊的數據,將新的數據緩存到數據庫中 new NewsDaoUtils(context).delete(); new NewsDaoUtils(context).saveNews(arrayList); } }catch (Exception e) { e.printStackTrace(); } return arrayList; } 3.3: 獲取服務端數據成功後,須要緩存到本地數據庫,緩存前須要清空本地數據庫。 4.建立一個Adapter繼承BaseAdapter,封裝4個方法,須要接收穫取的新聞數據 ok 5.將adapter設置給listview。 ok
github : 12306 出名 自定義的控件在佈局文件中的引用都須要指定類的完整路徑
1.自定義了一個MyImageview類繼承了Imageview,添加三個構造方法 2.添加一個setImageUrl方法接受一個圖片url 3.新建一個子線程去請求url獲取圖片資源 4.將獲取的圖片Bitmap經過handler發送給主線程,主線程設置給當前view. 5.在佈局中引用MyImageview,須要指定完成的包名路徑。
get方式和post方式的區別: 1.請求的URL地址不一樣: post:"http://192.168.13.83:8080/itheima74/servlet/LoginServlet" get:http://192.168.13.83:8080/itheima74/servlet/LoginServlet?username=root&pwd=123 2.請求頭不一樣: ****post方式多了幾個請求頭:Content-Length Cache-Control Origin openConnection.setRequestProperty("Content-Length", body.length()+""); openConnection.setRequestProperty("Cache-Control", "max-age=0"); openConnection.setRequestProperty("Origin", "http://192.168.13.83:8080"); ****post方式還多了請求的內容:username=root&pwd=123 //設置UrlConnection能夠寫請求的內容 openConnection.setDoOutput(true); //獲取一個outputstream,並將內容寫入該流 openConnection.getOutputStream().write(body.getBytes()); 3.請求時攜帶的內容大小不一樣 get:1k post:理論無限制