前三篇 講了listView和 handler,嘿嘿 這次再說一個 URL類 和 android的io,下一此就將這幾個內容 融合一下,做一個從服務器下載較大文件的小實例,怎麼樣期待吧 O(∩_∩)O哈哈~
先給大家 介紹一個可以模擬服務器的小工具,hfs,
一個小服務器,用tomcat也一樣,不過這個很小,只有800kb而已。做個測試夠用了,我會附加在博客後面的。
這個服務器沒啥好說的,唯一要注意的就是在項目中訪問服務器路徑的時候 要寫http://10.0.2.2:8080/path 有端口就寫端口號沒有就不用寫了,目錄別有中文和特殊符號就好,如果非得有,就涉及到瀏覽器的一些編碼問題了。
ok 現在說說怎麼使用URL類吧。。。
第一步:使用網絡資源的話 需要在清單文件中註冊權限:
這是文本編輯模式,看代碼的就是 加這樣一句話
<uses-permission android:name="android.permission.INTERNET"/>
給大家看看不加權限的後果撒。。。
項目 沒有報fc,但是在日誌裏面會打出這樣的日誌:
日誌的第一句就寫出 permission denied 的錯誤信息,這就是說 沒有註冊權限撒。。。
第二步:代碼篇:
import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import android.os.Bundle; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.ImageView; import android.widget.TextView; public class MainActivity extends Activity implements OnClickListener// 額注意這裏的點擊事件是android.view.View.OnClickListener包下的 { // 瀏覽器中的URL:http://localhost:8080/downloading/ // 項目中要報localhost改爲10.0.2.2 private final static String URL_PATH = "http://10.0.2.2:8080/test"; private final static String TEXT_PATH = "/text.txt"; private final static String IMAGE_PATH = "/img.png"; private final static String LOCALHOST_TXT_PATH = "/test.txt";//下面的項目用的。。。 private URL url; private URLConnection urlConn; private ImageView mImageView; private TextView mTextView; private TextView mLocalhost;//io代碼所用 private EditText mWrite;//io代碼所用 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.b_load_img).setOnClickListener(this); findViewById(R.id.b_load_text).setOnClickListener(this); findViewById(R.id.b_load_localhost).setOnClickListener(this); findViewById(R.id.b_write).setOnClickListener(this); mWrite = (EditText) findViewById(R.id.et_write); mTextView = (TextView) findViewById(R.id.tv_show_text); mImageView = (ImageView) findViewById(R.id.img_show_loadimg); mLocalhost = (TextView) findViewById(R.id.tv_localhost); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public void onClick(View v) { switch (v.getId()) { case R.id.b_load_text: loadText();// 加載文本 break; case R.id.b_load_img: loadImg();// 加載圖片 break; default: break; } } private void loadText()// 加載文本 { InputStream is = null;// 爲了關閉流文件java知識,不多解釋了。。。 try { url = new URL(URL_PATH + TEXT_PATH);// 獲取URL資源 拋出 // MalformedURLException urlConn = url.openConnection();// 獲得連接 拋出 IOException // 獲得連接後 就可以得到從服務器傳來的一個IO流 is = urlConn.getInputStream(); // input的流都有了 那些就 解析它咯; StringBuilder strbuff = new StringBuilder();// 有人會問這裏爲什麼不用StringBuffer // ,看源代碼就知道了buffer是線程安全的, // 在這裏完全沒必要,浪費資源 byte[] buffer = new byte[1024];// 定義一個字節緩衝數組 int len = 0; // len 用來接收從is中讀取到的字節數, // 有人會說 這個完全沒用麼,嘿嘿,如果有經驗的就會知道,buffer不一定會被完全充滿, // 沒充滿後面剩餘的部分按照java語法就全部賦值爲0了,那麼當你打印出讀取內容時就會發現一堆的亂碼 // 不相信的 話可是試試 把len去掉撒~,編程麼 就是在各種實驗中成長的撒~ while (-1 != (len = is.read(buffer))) { strbuff.append(new String(buffer, 0, len)); } mTextView.setText(strbuff.toString()); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if(is != null){ is.close(); } } catch (IOException e) { e.printStackTrace(); } } } private void loadImg()// 加載圖片 {//相比於解析文本 解析圖片就要輕鬆多了,android系統提供了一個Bitmap類和BitmapFactory來解析這傢伙 //看代碼: try { url = new URL(URL_PATH+IMAGE_PATH); urlConn = url.openConnection(); InputStream is = urlConn.getInputStream();//到這裏步驟跟加載文本都一樣撒。。 //開始加載圖片 Bitmap map = BitmapFactory.decodeStream(is);//額(⊙o⊙)… 圖片加載ok了 //不信 就把這傢伙放到 UI中試試。。。 mImageView.setImageBitmap(map); //不知道大家以前有沒有學過 怎麼設置 ImageView 顯示的圖片。。。 //這裏多說句吧。。。 //如果有資源id 的話 可以直接這樣設置的mImageView.setImageResource(R.drawable.ic_launcher); //android系統有很多設置圖片的方式setImageBitmap();只是其中一種而已。。。 } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
嘿嘿 不知道 ,大家記不記得 我第三篇博客有說過,向這樣的下載資源是屬於 耗時操作的。必須要在子線程中執行滴。。。嘿嘿先不急 先讓大夥兒體驗下 ANR的魅力。
有興趣的話 大家可以自己試試 看能不能解決這個ANR
第二話題:訪問本地資源
Android有4中訪問本地資源的方式先說說其中一種,訪問sdCard有很多人寫sdCard的path 時 喜歡直接寫”/mnt/sdcard”這是不規範的寫法。如果你的項目是定製的話,這樣就很可能訪問不到本地的sdcard了,正確的寫法應該是這樣滴:
File sdCardFile = Environment.getExternalStorageDirectory();//這個方式獲得的file就是sdCard的路徑
看看代碼吧:
第一步:訪問本地資源 同樣需要 用戶權限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
第二步:寫代碼咯
private void write() {// 寫入本地文件 : 需要權限:<uses-permission // android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> File sdCardFile = Environment.getExternalStorageDirectory();// 得到的是sdcard的目錄路徑 String path = sdCardFile.getAbsolutePath() + LOCALHOST_TXT_PATH;// 構建完整路徑 FileOutputStream fos = null; try { String str = mWrite.getText().toString();//從組件中得到輸入的值 fos = new FileOutputStream(path); fos.write(str.getBytes());//寫入文本 } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (fos != null) fos.close(); } catch (IOException e) { e.printStackTrace(); } } } private void localhost() {// 讀取本地文件 . 需要權限:<uses-permission // android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> //其實這個方法 跟 從網絡獲取資源差不多。。。 只是信息來源不同而已撒~~~ File sdCardFile = Environment.getExternalStorageDirectory();// 得到的是sdcard的目錄路徑 String path = sdCardFile.getAbsolutePath() + LOCALHOST_TXT_PATH;// 構建完整路徑 FileInputStream fis = null; try { fis = new FileInputStream(path); StringBuilder strBuff = new StringBuilder(); byte[] buffer = new byte[1024]; int len = 0; while(-1 != (len = fis.read(buffer))){ strBuff.append(new String (buffer,0,len)); } mLocalhost.setText(strBuff.toString()); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
這兩個代碼 我都寫在 URL的那個 項目裏面了, 那樣 大家就不用 弄那麼多項目了 看着就有點煩。。。是吧 O(∩_∩)O~