Android05

Android05

网络图片查看器

// 1.得到图片的url路径
URL url = new URL(path);

// 2.通过路径打开一个http的连接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();// http

// 3.得到服务器的返回信息(***)
int code = conn.getResponseCode(); // 200 OK 404 资源没找到 503服务器内部错误

if (code == 200) {
    InputStream is = conn.getInputStream();//(***)

    Bitmap bitmap = BitmapFactory.decodeStream(is);//(*)
    iv.setImageBitmap(bitmap);
    is.close();
}

4.权限
<uses-permission android:name="android.permission.INTERNET"/>

http请求的小细节

<EditText
    android:id="@+id/et_path"
    android:text="http://www.itheima.com/images_new/logo.jpg"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="请输入网络图片的路径" />

conn.setRequestMethod("GET");//设置请求参数为get, 默认的请求方式就是get
conn.setConnectTimeout(5000);//设置请求服务器的超时时间.

String type = conn.getContentType();
int length = conn.getContentLength();
System.out.println("服务器资源的长度:"+length);
System.out.println("服务器返回的数据类型:" + type);

ANR产生的原因

application not response :应用程序无响应

public void click(View view){
    try {
        System.out.println("线程名:"+Thread.currentThread().getName());
        Thread.sleep(10000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

理解(主线程不能阻塞,如果主线程睡了,后面有请求,就响应不了)

主线程就相当于人,人死了就什么都干不了,其他的子线程就没有什么用了.所以主线程是不能停掉的.

主线程模型

  • 放在子线程中(网络连接会有延迟,主线程就阻塞了,会有问题)

    public void viewImage(View view) {

    new Thread(){
        public void run() {
            //开启新的子线程 去请求网络 获取数据
            // 显示这个互联网上的图片
            try {
                // 1.得到图片的url路径
                URL url = new URL(path);
                // 2.通过路径打开一个http的连接
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();// http
                conn.setRequestMethod("GET");//设置请求参数为get, 默认的请求方式就是get
                conn.setConnectTimeout(5000);//设置请求服务器的超时时间.
                // 3.得到服务器的返回信息
                String type = conn.getContentType();
                int length = conn.getContentLength();
                System.out.println("服务器资源的长度:"+length);
                System.out.println("服务器返回的数据类型:" + type);
                int code = conn.getResponseCode(); // 200 OK 404 资源没找到 503服务器内部错误
                if (code == 200) {
                    InputStream is = conn.getInputStream();
                    //这里有问题
                    Bitmap bitmap = BitmapFactory.decodeStream(is);
                    iv.setImageBitmap(bitmap);    
                    is.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        };
    }.start();
    

    }

  • 放进子线中又有问题,是显示数据的时候,又要到主线程中显示,只有主线程才能修改ui.

android下的消息机制

//1.定义一个消息处理器(秘书)
private Handler handler = new Handler(){


//2.利用秘书给老板发消息,让主线程更新ui
Message msg = new Message();
msg.obj ="嘎嘎,哈哈哈,呱呱呱----"+i;
handler.sendMessage(msg);

private Handler handler = new Handler(){
    //3.秘书处理消息的方法
    @Override
    public void handleMessage(Message msg) {
        String text = (String) msg.obj;
        tv.setText(text);
        super.handleMessage(msg);
    }
};
  • 子线程不可以修改ui
  • 只有主线程才可以修改ui
  • 如果子线程想更新ui就必须利用消息机制处理
  • Handler:消息处理器,可以发送消息给主线程的消息队列
  • Message Queue :消息队列,主线程里面的一个消息队列
  • looper:轮询器,检查消息队列里面是否有消息

理解(子线程要在主线程中显示数据)

  • 子线程去找主线程中的Handler,将消息放进Message Queue中
  • 主线程有个looper,系统自动调用,看Message Queue中的数据
  • 有数据就取出来显示

网络图片查看器的完成

   //1.得到消息处理器
    private Handler handler = new Handler(){
        public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
            case SUCCESS:
                Bitmap bitmap = (Bitmap) msg.obj;
                iv.setImageBitmap(bitmap);
                break;
            case ERROR:
                Toast.makeText(MainActivity.this, "获取图片失败", 0).show();
                break;
            }
        };
    };

new Thread(){
    public void run() {

        Message msg = Message.obtain();//节约了内存
                msg.what = SUCCESS;
                msg.obj = bitmap;
                handler.sendMessage(msg);
                is.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
            Message msg = Message.obtain();
            msg.what = ERROR;
            handler.sendMessage(msg);
        }

    };
}.start();

网页源码查看器

  • 工具类将流转换成字符串

添加一个弹窗进度框

public class StreamTools {
/**
 * 工具方法
 * @param is 输入流
 * @return 文本字符串
 * @throws Exception
 */
public static String readStream(InputStream is) throws Exception{
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    int len = -1;
    while((len = is.read(buffer))!=-1){
        baos.write(buffer, 0, len);
    }
    is.close();
    String temp =  baos.toString();
    if(temp.contains("charset=utf-8")){
        return temp;
    }else if(temp.contains("gb2312")){
        return baos.toString("gb2312");
    }return null;
}

useragent的使用

conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C; InfoPath.2");                    

中文乱码问题的处理

String temp =  baos.toString();
if(temp.contains("charset=utf-8")){
    return temp;
}else if(temp.contains("gb2312")){
    return baos.toString("gb2312");
}return null;

访问网络获取手机归属地

  • 网络请求数据+显示
  • xml解析

天气预报案例-json数据的解析

String path = "http://wthrcdn.etouch.cn/weather_mini?city="+URLEncoder.encode(cityname,"utf-8");

String json = StreamTools.readStream(is);
    JSONObject jsonObj = new JSONObject(json);
    String result = jsonObj.getString("desc");
    System.out.println(result);
    if("OK".equals(result)){
        //请求成功
        JSONObject dataJSON = jsonObj.getJSONObject("data");
        JSONArray  array = dataJSON.getJSONArray("forecast");
        Message msg = Message.obtain();
        msg.obj = array;
        msg.what = SUCCESS;
        handler.sendMessage(msg);

    }else{
        //城市信息不正确.
        Message msg = Message.obtain();
        msg.what = ERROR_CITY;
        handler.sendMessage(msg);
    }
}

    JSONArray array = (JSONArray) msg.obj;
    tv_result_day1.setText(array.getJSONObject(0).toString());

新闻客户端的需求和服务器搭建

  • apache-tomcat-7.0.53
  • G:\apache-tomcat-7.0.53\webapps\ROOT\new.xml / img

连接服务器解析数据

public class NewsInfoService {
    /**
     * 获取服务器最新的所有的新闻信息
     * 
     * @param path   服务器的路径
     * @return null 请求失败
     */
public static List<NewsItem> getAllNews(String path) throws Exception {
    List<NewsItem> newsItems = new ArrayList<NewsItem>();//所有新闻的集合
    URL url = new URL(path);
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setRequestMethod("GET");
    conn.setConnectTimeout(5000);
    Thread.sleep(3000);
    int code = conn.getResponseCode();
    if (code == 200) {
        InputStream is = conn.getInputStream();
        XmlPullParser parser = Xml.newPullParser();
        parser.setInput(is, "utf-8");
        int eventType = parser.getEventType();
        NewsItem newsItem = null;
        while (eventType != XmlPullParser.END_DOCUMENT) {
            switch (eventType) {
            case XmlPullParser.START_TAG:
                if("item".equals(parser.getName())){
                    newsItem = new NewsItem();//新闻数据要开始了创建出来对象
                }else if("title".equals(parser.getName())){
                    newsItem.setTitle(parser.nextText());
                }else if("description".equals(parser.getName())){
                    newsItem.setDescription(parser.nextText());
                }else if("image".equals(parser.getName())){
                    newsItem.setImage(parser.nextText());
                }else if("type".equals(parser.getName())){
                    newsItem.setType(parser.nextText());
                }else if("comment".equals(parser.getName())){
                    newsItem.setComment(Integer.parseInt(parser.nextText()));
                }
                break;
            case XmlPullParser.END_TAG:
                if("item".equals(parser.getName())){
                    newsItems.add(newsItem);
                }
                break;
            }
            eventType = parser.next();
        }
        return newsItems;
    } else {
        return null;
    }}}

------------------------------------------------
items = NewsInfoService.getAllNews(getResources()
                            .getString(R.string.serverpath));

数据的界面展现&正在加载的进度

 <ListView
        android:id="@+id/lv"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <LinearLayout
        android:id="@+id/ll_loading"
        android:visibility="invisible"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="vertical" >
        <ProgressBar 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            />
        <TextView 
             android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="正在拼命加载中..."
            />

    ----------------------------------------------------
        Handler
        ll_loading.setVisibility(View.INVISIBLE);

    ---------------------------------------------------
    // 设置新闻数据到界面. mainActivtyx显示
    ll_loading.setVisibility(View.VISIBLE);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值