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(){//处理消息@Overridepublic void handleMessage(Message msg) {//1.先获取消息携带的数据 数据是怎么携带的就怎么取String content = (String) msg.obj;//2在这个方法里面更新UItv_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
<ScrollViewandroid:layout_width="match_parent"android:layout_height="wrap_content"><TextViewandroid: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线程@Overridepublic 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.SmartImageViewandroid:id="@+id/iv_icon"android:layout_width="wrap_content"android:src="@mipmap/ic_launcher"android:layout_height="wrap_content"></com.loopj.android.image.SmartImageView><TextViewandroid: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"/><TextViewandroid: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"/><TextViewandroid: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() {@Overridepublic 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() {@Overridepublic 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]获取解析器 xmlpullparserXmlPullParser 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{@Overridepublic int getCount() {return lists.size();}@Overridepublic Object getItem(int position) {return null;}@Overridepublic long getItemId(int position) {return 0;}//获取一个view 用来展示是每个条目的内容@Overridepublic 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.SmartImageViewandroid: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);
本文详细介绍了一个基于Android平台的网络编程示例,包括网页源码查看器的开发过程、图片查看器的设计思路及综合案例实现。文章讲解了如何利用HTTPURLConnection进行网络请求、处理网络异常、实现线程间的通信以及XML数据的解析等关键技术。

被折叠的 条评论
为什么被折叠?



