android的 网络下载和数据持久化

前三篇 讲了listViewhandler,嘿嘿 这次再说一个 URL类 和 androidio,下一此就将这几个内容 融合一下,做一个从服务器下载较大文件的小实例,怎么样期待吧 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

第二话题:访问本地资源

Android4中访问本地资源的方式先说说其中一种,访问sdCard有很多人写sdCardpath 时 喜欢直接写/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~



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章