网络编程1

来源:互联网 发布:linux如何创建目录链接 编辑:程序博客网 时间:2024/06/05 06:45

1.网页源码查看器

代码实现步骤
[1]搭建UI
这里写图片描述
[2]httpurlconnection类基本用法

public void click(View view) {​        try {            //1.获取用户输入的路径            String path = et_path.getText().toString().trim();            //2.访问这个路径            URL url = new URL(path);            //3.通过url对象获取httpurlconnection实例  该实例用于发送或者接收数据            HttpURLConnection conn = (HttpURLConnection) url.openConnection();            //4.设置一下联网超时时间            conn.setConnectTimeout(5000);            //5.设置一下请求的方式            conn.setRequestMethod("GET"); //默认是get请求            //6.获取服务器返回状态码            int code = conn.getResponseCode();            //7.对code做判断            if (code == 200){                //8.获取服务器返回的数据                InputStream is = conn.getInputStream();                //9.把流的数据读取出来  展示到textview上  由于把is转换为String是一个非常常见的操作 所以我们可以做一个工具类.                 String content = StreamUtils.readStream(is);                //10.展示数据                 tv_content.setText(content);            }​​        } catch (Exception e) {            e.printStackTrace();        }​    }

[3]把流转换为String工具类

public class StreamUtils {​    public static String readStream(InputStream is) throws  Exception{​            //1.创建内存输出流            ByteArrayOutputStream  baso = new ByteArrayOutputStream();            int len = 0;            byte[] buf = new byte[1024];            while((len = is.read(buf))!=-1){                baso.write(buf,0,len);            }            //2.关流            is.close();            //baso 关闭此流无效            return baso.toString();​    }}

[4]联网要加上联网权限

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

当加上权限后 也会报如下错误

 android.os.NetworkOnMainThreadException  主线程(UI线程)访问网络的异常.  主线程这个概念是谷歌提出的.

为什么会报这个异常.谷歌要求 在主线程不能进行耗时(拷贝数据 连接网络)的操作,如果在主线程中进行耗时操作会报anr(应用无响应)异常; 如何解决?我们可以自己创建一个线程 来访问网络.
[5]当我们把访问访问的操作放到子线程又会报如下错误:

android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.只有主线程(UI线程)才可以更新UI

[6].handler(助手)的使用 —->负责线程的切换
6.1创建handler对象

private Handler handler = new Handler(){        //处理消息        @Override        public void handleMessage(Message msg) {​            //1.先获取消息携带的数据  数据是怎么携带的就怎么取             String content = (String) msg.obj;​            //2在这个方法里面更新UI            tv_content.setText(content);​        }    };

6.2 发消息

 //9.1构造message对象                        Message msg = new Message();                        //9.2 通过msg对象携带数据                        msg.obj = content;​                        //10.使用handler进行线程的切换                        handler.sendMessage(msg); ///---->handleMessage方法就会执行 这样就从子线程切换到了主线程

7.scrollView 垂直滚动的view

<ScrollView        android:layout_width="match_parent"        android:layout_height="wrap_content">        <TextView            android:id="@+id/tv_content"            android:layout_width="match_parent"            android:layout_height="match_parent"            android:text="Hello World!" /></ScrollView>

注意:scrollView控件只能包裹一个孩子.如果想包裹多个在外面套一个布局.

2.handler原理
这里写图片描述

3.图片查看器

[3.1]和源码查看器区别:1 UI不一样                                2 数据展示的方式不一样                               3  访问路径的不一样 [3.2] runOnUIthread
runOnUiThread(new Runnable() { //这个方法如果是在ui线程调用 那么这个方法会立即执行 如果调用这个方法不是在UI线程 那么要执行的动作也会运行到Ui线程                                @Override                                public void run() {                                    //run方法里面执行逻辑  运行在主线程                                    Toast.makeText(MainActivity.this, "服务器忙", Toast.LENGTH_SHORT).show();                                }                            });
[3.3]bitmapFactory  位图工厂 
 final Bitmap bitmap = BitmapFactory.decodeStream(is);

4.综合案例

案例设计到知识点:listview —>baseAdapter tomcat xml(xml解析) url httpurlconnection 开线程 handler
案例开发的流程
开发这样一个程序 最少3个人 一个android客户端,一个UI设计师,做服务器开发人员. 产品经理(微信).
代码实现过程:
1.画UI

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="100dp">​​    <com.loopj.android.image.SmartImageView        android:id="@+id/iv_icon"        android:layout_width="wrap_content"        android:src="@mipmap/ic_launcher"        android:layout_height="wrap_content"></com.loopj.android.image.SmartImageView>​​​    <TextView        android:id="@+id/tv_title"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="今日头条"        android:textSize="22sp"        android:textColor="#000000"        android:layout_marginLeft="5dp"        android:layout_marginTop="5dp"        android:layout_toRightOf="@id/iv_icon"        /><TextView        android:id="@+id/tv_desc"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="今日头条老师老师过来过时了阿拉嘎嘎嘎"        android:textSize="17sp"        android:textColor="#999999"        android:layout_marginLeft="5dp"        android:layout_marginTop="5dp"        android:layout_toRightOf="@id/iv_icon"        android:layout_below="@id/tv_title"        /><TextView        android:id="@+id/tv_type"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="跟帖"        android:textSize="20sp"        android:textColor="#ff0000"        android:layout_alignParentRight="true"        android:layout_alignParentBottom="true"        />​​</RelativeLayout>

2.搭建服务器 去服务器取数据

private void initData() {            new Thread() {                @Override                public void run() {                    try {                        //1.定义访问的路径                        String path = "http://192.168.126.62:8080/news/news.xml";                        //2.访问这个路径                        URL url = new URL(path);                        //3.通过url对象获取httpurlconnection实例  该实例用于发送或者接收数据                        HttpURLConnection conn = (HttpURLConnection) url.openConnection();                        //4.设置一下联网超时时间                        conn.setConnectTimeout(5000);                        //5.设置一下请求的方式                        conn.setRequestMethod("GET"); //默认是get请求                        //6.获取服务器返回状态码                        int code = conn.getResponseCode();                        //7.对code做判断                        if (code == 200) {                            //8.获取服务器返回的数据                            InputStream is = conn.getInputStream();                            //9.把流的数据读取出来    解析xml 把xml解析的数据封装到list<bean>                            lists = NewsXmlUtils.parserXml(is);​                            //10.把集合里面的数据 通过适配器展示出来                            runOnUiThread(new Runnable() {                                @Override                                public void run() {                                    //11.更新适配器                                    lv.setAdapter(new MyAdaper());                                }                            });​                        }​                    } catch (Exception e) {                        e.printStackTrace();​                    }​​                }            }.start();​​        }

3.对数据进行解析 xml解析

 public static List<News> parserXml(InputStream is) {​        List<News> lists=null;        News news = null;        // [1]获取解析器 xmlpullparser        XmlPullParser parser = Xml.newPullParser();        // [2]设置解析器要解析的内容        try {            parser.setInput(is, "utf-8");​            // [3]获取解析器的事件类型            int eventType = parser.getEventType();            // [4]不到文件结尾就一直解析            while (eventType != XmlPullParser.END_DOCUMENT) {                // [5]具体判断一下解析到的标签 然后把我们关系的数据取出来 封装到集合中                switch (eventType) {                    case XmlPullParser.START_TAG: //代表解析到的所有开始的标签//[6]具体判断一下解析到的是哪个开始标签                        if ("channel".equals(parser.getName())) {                            //[7]创建一个集合对象                            lists =new ArrayList<News>();                        }else if ("item".equals(parser.getName())) {                            //[8]创建javabean对象                            news = new News();​                        }else if ("title".equals(parser.getName())) {                            //[8.1]获取文本的数据                            news.setTitle(parser.nextText());​                        }else if ("description".equals(parser.getName())) {                            //[8.1]获取文本的数据                            news.setDescription(parser.nextText());​                        }else if ("image".equals(parser.getName())) {                            //[8.1]获取文本的数据                            news.setImagepath(parser.nextText());​                        }else if ("type".equals(parser.getName())) {                            //[8.1]获取文本的数据                            news.setType(parser.nextText());​                        }else if ("comment".equals(parser.getName())) {                            //[8.1]获取文本的数据                            news.setComment(parser.nextText());                        }​                        break;​                    case XmlPullParser.END_TAG:   //解析到的所有的结束标签if("item".equals(parser.getName())){                            //把bean对象加入到集合中                            lists.add(news);                        }​                        break;                }​                // 不停解析                eventType = parser.next();            }            //最后把集合对象返回            return lists;​​        } catch (Exception e) {            e.printStackTrace();            return null;        }​    }

4.定义数据适配器

class  MyAdaper extends BaseAdapter{​        @Override        public int getCount() {            return lists.size();        }​        @Override        public Object getItem(int position) {            return null;        }​        @Override        public long getItemId(int position) {            return 0;        }​        //获取一个view  用来展示是每个条目的内容        @Override        public View getView(int position, View convertView, ViewGroup parent) {​            //1.优化             View view;             if (convertView == null){                 view = View.inflate(getApplicationContext(),R.layout.item,null);             }else{                 view = convertView;             }​            //2.找的条目控件            TextView tv_title = (TextView) view.findViewById(R.id.tv_title);            TextView tv_desc = (TextView) view.findViewById(R.id.tv_desc);            TextView tv_type = (TextView) view.findViewById(R.id.tv_type);            SmartImageView siv = (SmartImageView) view.findViewById(R.id.iv_icon);​​            //3.更新UI的数据            News news = lists.get(position);            tv_title.setText(news.getTitle());   //更新标题            tv_desc.setText(news.getDescription()); //更新标题描述            //4更新新闻类型            String typee = news.getType();            int type = Integer.parseInt(typee);            switch (type){                case 1:                    tv_type.setText("国内");                    break;                case 2:                    tv_type.setText("娱乐");                    break;                case 3:                    tv_type.setText("体育");                    break;            }​            //5.展示图片信息            String imagepath = news.getImagepath();            siv.setImageUrl(imagepath);​            return view;        }    }

5.smartImageview
5.1要先声明 要求这个类的完整包名和类名

<com.loopj.android.image.SmartImageView        android:id="@+id/iv_icon"        android:layout_width="wrap_content"        android:src="@mipmap/ic_launcher"        android:layout_height="wrap_content"></com.loopj.android.image.SmartImageView>

5.2找的控件 展示数据

  //5.展示图片信息            String imagepath = news.getImagepath();            siv.setImageUrl(imagepath);
原创粉丝点击