android的 网络下载和数据持久化
前三篇 讲了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~
更多相关文章
- 解决Android模拟器不能联网问题
- Android卸载监听之后访问后台或者弹出一个网页
- android在更新ADT以后报java.lang.NoClassDefFound的解决办法
- Android加载不同DPI资源与内存消耗之间的关系
- Android仿“守望先锋”加载动画
- 【Android快捷开发笔记系列】——Data Binding
- Android开发之adb && 破解开屏图案 && 代码判断当前是否处于锁屏
- Android中AsyncTask的处理后台耗时操作(如list排序,进度加载)
- Android上面搭建 Opencv的开发环境+摄像头开启