1.网页源码查看器
浏览器按f12
[1]httpurlconnection:用于发送或接收数据
[2]ScrollView:只能包裹一个孩子
实现代码如下:
[1]清单文件加权限:<uses-permission android:name="android.permission.INTERNET"/>
[2]activity_main.xml代码如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.itheima.look.MainActivity"
tools:ignore="MergeRootFrame" >
<EditText
android:id="@+id/et_path"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="https://www.baidu.com"
android:hint="请输入查看网址" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="click"
android:text="查看" />
<ScrollView
android:id="@+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/tv_result"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="haha"
/>
</ScrollView>
</LinearLayout>
[3]MainActivity代码如下:
protected final int REQUESTSUCESS = 0; // ctrl + shift + X Y
protected final int REQUESTNOTFOUND = 1;
protected final int REQUESTEXCEPTION = 2;
private EditText et_path;
private TextView tv_result;
// 在主线程中定义一个handler
private Handler handler = new Handler() {
// 这个方法是在主线程里面执行的
public void handleMessage(android.os.Message msg) {
// 所以就可以在主线程里面更新ui了
// 1.区别一下发送的是哪条消息
switch (msg.what) {
case REQUESTSUCESS://代表请求成功
String content=(String)msg.obj;
tv_result.setText(content);
break;
case REQUESTNOTFOUND://代表资源不存在
Toast.makeText(getApplicationContext(), "请求资源不存在", 0).show();
break;
case REQUESTEXCEPTION://代表异常
Toast.makeText(getApplicationContext(), "服务器忙 请稍后...", 1).show();
break;
default:
break;
}
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_path = (EditText) findViewById(R.id.et_path);
tv_result = (TextView) findViewById(R.id.tv_result);
// 1.1打印当前线程的名字
System.out.println("当前线程的名字:" + Thread.currentThread().getName());
}
// 2.点击按钮进行查看 指定路径的源码
public void click(View v) {
// 2.0创建一个子线程
new Thread() {
@Override
public void run() {
try {
// 2.1获取源码路径
String path = et_path.getText().toString().trim();
// 2.2创建URL对象指定我们要访问的网址(路径)
URL url = new URL(path);
// 2.3拿到httpurlconnection对象 用于发送或者接受数据
HttpURLConnection conn = (HttpURLConnection) url
.openConnection();
// 2.4设置发送get请求
conn.setRequestMethod("GET");// get要求大写 默认就是get请求
// 2.5设置请求超时时间
conn.setConnectTimeout(5000);
// 2.6获取服务器返回的状态码
int code = conn.getResponseCode();
// 2.7如果code==200说明请求成功
if (code == 200) {
// 2.8获取服务器返回的数据 是以流的形式返回的。 由于把流转化成字符串是一个非常常见的操作
// 所以我抽出一个工具类(utils)
InputStream in = conn.getInputStream();
// 2.9使用我们定义的工具类 把in转化成String
String content = StreamTools.readStream(in);
// 2.9.0创建messgage对象
Message msg=new Message();
msg.what=REQUESTSUCESS;
msg.obj=content;
//2.9.1拿着我们创建的handler(助手)告诉系统 说我要更新ui
handler.sendMessage(msg);//发送一条消息,消息(msg)里把数据放到msg里.handleMessage方法就会执行
//2.9.2把流里面的数据展示到textview上 这句话就属于更新ui的逻辑
//tv_result.setText(content);
}else{
//请求资源不存在 Toast是一个view 也不能在线程更新ui
Message msg=new Message();
msg.what=REQUESTNOTFOUND;//代表哪条消息
handler.sendMessage(msg);
}
} catch (Exception e) {
e.printStackTrace();
Message msg=new Message();
msg.what=REQUESTEXCEPTION;//代表哪条消息
handler.sendMessage(msg);//代表消息
}
}
}.start();
}
[4]StreamTools工具类,代码如下:
//把一个inputStream转化成一个String
public static String readStream(InputStream in) throws Exception{
//定义一个内存输出流
ByteArrayOutputStream baos=new ByteArrayOutputStream();
int len=-1;
byte[] buffer=new byte[1024];//1kb
while((len=in.read(buffer))!=-1){
baos.write(buffer,0,len);
}
in.close();
String content=new String(baos.toByteArray());
return content;
}
【ANR】:在Android上,如果你的应用程序有一段时间响应不够灵敏,系统会向用户显示一个对话框,这个对话框称作应用程序无响应(ANR:Application Not Responding)对话框。
用户可以选择“等待”而让程序继续运行,也可以选择“强制关闭”。所以一个流畅的合理的应用程序中不能出现anr,而让用户每次都要处理这个对话框。因此,在程序里对响应性能的设计很重要,这样系统不会显示ANR给用户。
默认情况下,在android中Activity的最长执行时间是5秒,BroadcastReceiver的最长执行时间则是10秒。
2.消息机制的写法
[1]anr Application not response应用无响应 主线程(UI线程)
[2]如果在主线程中进行了耗时的操作(比如连接网络 拷贝大的数据) Thread.sleep()
[3]避免anr 可以把耗时的操作 放到子线程中 自己在创建一个线程
[4]在4.0之后谷歌强制要求连接网络不能再主线程进行访问
W/System.err(1638): android.os.NetworkOnMainThreadException
[5]只有主线程(ui线程)才可以更新ui
W/System.err(1708):android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
[6]消息机制
3.handler原理
handler使用步骤
[1]在主线程定义一个Handler
private Handler handler = new Handler();
[2]使用handler,重写handler的里面的handleMessage方法
public void handleMessage(android.os.Message msg) {}
[3]拿着我们在主线程创建的handler去子线程发消息
handler.sendMessage(msg);
[4]handleMessage方法就会执行 在这个方法里面去更新ui
handler的作用是用来发送消息和处理消息的
Looper的作用是去消息队列里面取消息
Looper是在主线程一创建 Looper就有了
子线程 ----x---》UI ,子线程(一般)不能直接更新ui,只能用handler发送了一条消息
messagequeue-----(handler-->handlemessage)---->Looper消息循环器---->|
| |
|<<------------------------------------(主线程)-----------------<<- |
规则:不管你什么版本的手机 只要做耗时的操作(比如连接网络 比如拷贝大的数据 等等)就自己开一个子线程,获取数据后要更新ui,就使用Handler就可以了
4.图片查看器
[1]把流消息转换成bitmap对象:bitmapFactory.decodeStream(inputStream in)
[2]最后记得加上网络访问权限
[1]activity_main.xml代码如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.itheima.look.MainActivity"
tools:ignore="MergeRootFrame" >
<EditText
android:id="@+id/et_path"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="https://www.baidu.com/img/270_36f64e1b77eb344d543d6e20029dbb92.png"
android:hint="请输入查看图片网址" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="click"
android:text="查看" />
<ImageView
android:id="@+id/iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
[2]MainActivity代码如下:
private EditText et_path;
private ImageView iv;
// 创建handler对象
private Handler handler = new Handler() {
//处理消息
public void handleMessage(android.os.Message msg) {
Bitmap bitmap=(Bitmap) msg.obj;
iv.setImageBitmap(bitmap);
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//1.找到我们关心的控件
et_path = (EditText) findViewById(R.id.et_path);
iv = (ImageView) findViewById(R.id.iv);
}
// 2.点击按钮进行查看 指定路径的源码
public void click(View v) {
new Thread() {
@Override
public void run() {
try {
// 2.1获取访问图片的路径
String path = et_path.getText().toString().trim();
File file = new File(getCacheDir(), Base64.encodeToString(
path.getBytes(), Base64.DEFAULT));
if (file.exists() && file.length() > 0) {
// 使用缓存的图片
System.out.println("使用缓存图片");
final Bitmap cacheBitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
System.out.println("使用缓存图片"+file.getAbsolutePath());
// 把cacheBitmap显示到iv上
//Message msg=Message.obtain();
//msg.obj=cacheBitmap;
//handler.sendMessage(msg);//发消息
runOnUiThread(new Runnable() {
@Override
public void run() {
iv.setImageBitmap(cacheBitmap);
}
});
}else{
//第一次访问 联网获取数据
System.out.println("第一次访问连接网络");
//2.2创建url对象
URL url=new URL(path);
//2.3获取HttpURLConnection
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//2.4设置请求的方式
conn.setRequestMethod("GET");
//2.5设置超时时间
conn.setConnectTimeout(5000);
//2.6获取服务器返回的状态码
int code=conn.getResponseCode();
if(code==200){
//2.7获取图片的数据 不管是什么数据(txt文本 图片数据)都是以流的形式返回
InputStream in = conn.getInputStream();
//2.7.1缓存图片 谷歌给我们提供了一个缓存目录
FileOutputStream fos=new FileOutputStream(file);
int len=-1;
byte[] buffer=new byte[1024];//1kb
while((len=in.read(buffer))!=-1){
fos.write(buffer,0,len);
}
fos.close();
in.close();
//2.8通过位图工厂 获取bitmap(bitmap)
final Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
//这句api 不管你在什么位置上调用 action都运行到ui线程里
runOnUiThread(new Runnable() {
public void run() {
//run方法一定执行在ui线程里
//2.9把bitmap显示到iv上
iv.setImageBitmap(bitmap);
}
});
//Message msg=Message.obtain();//使用msg的静态方法 可以减少对象的创建
//msg.obj=bitmap;
//handler.sendMessage(msg);//发送消息
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
5.runOnUiThread写法
[1]如果仅仅就是更新ui 那么就用runOnUiThread这个api就可以
[2]有的时候可以通过Handler 发送消息 携带数据 这时候必须的用handler
6.常见消息Api
handler:
//2000秒钟后 执行run方法
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
tv.setText("哈哈哈");
}
}, 2000);
定时器Timer:
timer = new Timer();
task = new TimerTask() {
@Override
public void run() {
//System.out.println("hehehe");
runOnUiThread(new Runnable() {
public void run() {
tv.setText("呵呵呵");
}
});
}
};
//3秒后 每隔1秒执行一次run方法
timer.schedule(task, 3000, 1000);
//销毁
timer.cancel();
task.cancel();
7.新闻客户端
[1]UI效果是公司里面美工去画的
[2]应用的传输数据 定义接口
[3]关于xml的数据 是服务器开发人员通过一定的技术手段返回的 对应Android开发人员我们要回解析就ok
把我们关心的数据取出来 展示到Android中控件上
[1]权限<uses-permission android:name="android.permission.INTERNET"/>
[2]activity_main.xml代码如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<ListView
android:id="@+id/lv"
android:layout_width="match_parent"
android:layout_height="match_parent"
></ListView>
</RelativeLayout>
[3]item.xml代码如下:
<?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="match_parent" >
<com.loopj.android.image.SmartImageView
android:id="@+id/iv_icon"
android:layout_width="80dp"
android:layout_height="80dp"
android:src="@drawable/ic_launcher"
/>
<TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_toRightOf="@id/iv_icon"
android:ellipsize="end"
android:singleLine="true"
android:text="啊结果了敬爱个路口就爱看的两个件大事"
android:textColor="#000000"
android:textSize="18sp"
/>
<TextView
android:id="@+id/tv_desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/tv_title"
android:layout_marginTop="6dp"
android:layout_toRightOf="@id/iv_icon"
android:ellipsize="end"
android:maxLines="2"
android:text="啊结果了敬爱个路口就爱看的两个件上的故事格式的公共的十大歌手大事"
android:textColor="#999999"
android:textSize="14sp"
/>
<TextView
android:id="@+id/tv_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="跟帖"
android:textColor="#ff0000"
android:layout_marginRight="3dp"
android:layout_alignBottom="@id/iv_icon"
android:textSize="14sp"
/>
</RelativeLayout>
[4]News javabean代码如下:
private String title;
private String description;
private String image;
private String type;
private String comment;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
[5]XmlParserUtils工具类代码如下:
//解析xml的业务方法
public static List<News> parserXml(InputStream in) throws Exception{
List<News> newsLists=null;
News news=null;
//1.获取xml的解析器
XmlPullParser parser = Xml.newPullParser();
//2.设置解析器 要解析的内容
parser.setInput(in, "utf-8");
//3.获取解析的事件类型
int type = parser.getEventType();
//4.不停的向下解析
while(type!=XmlPullParser.END_DOCUMENT){
//5.具体判断一下解析的是开始节点 还是结束节点
switch (type) {
case XmlPullParser.START_TAG://解析开始节点
//6.具体判断一下解析的是哪个开始标签
if("channel".equals(parser.getName())){
//创建一个list集合
newsLists=new ArrayList<News>();
}else if("item".equals(parser.getName())){
news=new News();
}else if("title".equals(parser.getName())){
news.setTitle(parser.nextText());
//System.out.println("title(nexttext):"+parser.nextText()+",(gettext):"+parser.getText());
}else if("description".equals(parser.getName())){
news.setDescription(parser.nextText());
//System.out.println("description(nexttext):"+parser.nextText()+",(gettext):"+parser.getText());
}else if("image".equals(parser.getName())){
news.setImage(parser.nextText());
//System.out.println("image(nexttext):"+parser.nextText()+",(gettext):"+parser.getText());
}else if("type".equals(parser.getName())){
news.setType(parser.nextText());
//System.out.println("type(nexttext):"+parser.nextText()+",(gettext):"+parser.getText());
}else if("comment".equals(parser.getName())){
news.setComment(parser.nextText());
//System.out.println("comment(nexttext):"+parser.nextText()+",(gettext):"+parser.getText());
}
break;
case XmlPullParser.END_TAG://解析结束标签
if("item".equals(parser.getName())){
//把javabean添加到集合
newsLists.add(news);
}
break;
default:
break;
}
//不停的向下解析
type=parser.next();
}
return newsLists;
}
[6]MainActivity代码如下:
private ListView lv;
private List<News> newsLists;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = (ListView) findViewById(R.id.lv);
// 2.准备listview要显示的数据 去服务器取数据 进行封装
initListData();
}
// 准备listview的数据
private void initListData() {
new Thread() {
public void run() {
try {
// 2.去服务器取数据 http://192.168.10.98:8080/news.xml
String path = "http://192.168.10.98:8081/news.xml";
// 2.2创建URL对象指定我们要访问的网址(路径)
URL url = new URL(path);
// 2.3拿到HttpURLConnection对象 用于发送或者接受数据
HttpURLConnection conn = (HttpURLConnection) url
.openConnection();
// 2.4设置发送get请求
conn.setRequestMethod("GET");// get要求大写 默认就是get请求
// 2.5设置请求超时时间
conn.setConnectTimeout(5000);
// 2.6获取服务器返回的状态码
int code = conn.getResponseCode();
// 2.7如果code==200说明请求成功
if (code == 200) {
// 2.8获取服务器返回的数据 是以流的形式返回的
InputStream in = conn.getInputStream();
newsLists = XmlParserUtils.parserXml(in);
System.out.println("newsLists:" + newsLists.size());
runOnUiThread(new Runnable() {
public void run() {
// 3.更新ui 把数据展示到listview上
lv.setAdapter(new MyAdapter());
}
});
}
} catch (Exception e) {
e.printStackTrace();
}
};
}.start();
}
// 定义数据适配器
private class MyAdapter extends BaseAdapter {
@Override
public int getCount() {
return newsLists.size();
}
@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view;
if (convertView == null) {
view = View.inflate(getApplicationContext(), R.layout.item,
null);
} else {
view = convertView;
}
// 1.找到控件 显示集合里面的数据
SmartImageView iv_icon = (SmartImageView) view
.findViewById(R.id.iv_icon);
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);
// 1.1展示图片的数据
String imageUrl = newsLists.get(position).getImage();
// 展示图片
iv_icon.setImageUrl(imageUrl, R.drawable.bg);
// 2.显示数据
tv_title.setText(newsLists.get(position).getTitle());
tv_desc.setText(newsLists.get(position).getDescription());
String typee = newsLists.get(position).getType();
String comment = newsLists.get(position).getComment();
int type = Integer.parseInt(typee);
switch (type) {
case 1:
tv_type.setText(comment+"国内");
break;
case 2:
tv_type.setText("跟帖");
break;
case 3:
tv_type.setText("国外");
break;
default:
break;
}
return view;
}
}
8.开源项目smartimageview介绍
[1]把com包 源码包拷贝到当前工程
[2]在使用smartimageview类的时候 在布局里面定义的时候 一定是这个类的完整包名+类名
9.smartimageview原理介绍
自定义smartimageview:
[1]activity_main.xml代码如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<com.itheima.customsmartimg.MySmartImageView
android:id="@+id/iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</RelativeLayout>
[2]MainActivity代码如下:
MySmartImageView iv = (MySmartImageView)findViewById(R.id.iv);
iv.setImageUrl("https://www.baidu.com/img/270_36f64e1b77eb344d543d6e20029dbb92.png",R.drawable.bg);
[3]MySmartImageView代码如下:
public class MySmartImageView extends ImageView {
private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case 1:// 代表请求成功
Bitmap bitmap = (Bitmap) msg.obj;
// 显示数据
MySmartImageView.this.setImageBitmap(bitmap);
break;
case 2:// 请求失败 显示一个默认图片
int resource = (Integer) msg.obj;
MySmartImageView.this.setBackgroundResource(resource);
break;
case 3:
int resource1 = (Integer) msg.obj;
MySmartImageView.this.setBackgroundResource(resource1);
break;
default:
break;
}
};
};
public MySmartImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
//这个类 在布局文件中使用的时候 调用2个参数的构造方法
public MySmartImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
//一个参数的构造方法 在new代码初始化的时候调用
public MySmartImageView(Context context) {
super(context);
}
// 显示图片的方法 path是传过来的url地址
public void setImageUrl(final String path) {
new Thread() {
public void run() {
try {
//2.2创建URL对象指定我们要访问的网址(路径)
URL url=new URL(path);
//2.3拿到httpurlconnection对象 用于发送或接收数据
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//2.4设置发送get请求
conn.setRequestMethod("GET");//get要求大写 默认就是get请求
//2.5设置请求超时时间
conn.setConnectTimeout(5000);
//2.6获取服务器返回的状态码
int code = conn.getResponseCode();
//2.7如果code==200说明请求成功
if(code==200){
//2.8获取服务器返回的数据 是以流的形式返回的 由于把流转化成字符串是一个非常常见的操作
//所以抽出一个工具类(utils)
InputStream in = conn.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(in);
//创建message对象
Message msg=Message.obtain();
msg.obj=bitmap;
handler.sendMessage(msg);//发送消息
}
} catch (Exception e) {
e.printStackTrace();
}
};
}.start();
}
//显示图片的方法 path是传过来的url地址
public void setImageUrl(final String path,final int resource){
new Thread(){
public void run() {
try {
//2.2创建url对象 指定我们要访问的网址 (路径)
URL url=new URL(path);
//2.3拿到httpurlconnection对象 用于发送或者接受数据
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//2.4设置发送get请求
conn.setRequestMethod("GET");//get要求大写 默认就是get请求
//2.5设置请求超时时间
conn.setConnectTimeout(5000);
//2.6获取服务器返回的状态码
int code = conn.getResponseCode();
//2.7如果code==200说明请求成功
if(code==200){
//2.8获取服务器返回的数据
InputStream in = conn.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(in);
//创建message对象
Message msg=Message.obtain();
msg.what=1;
msg.obj=bitmap;
handler.sendMessage(msg);//发送消息
}else{
//请求失败
Message msg=Message.obtain();
msg.what=2;
msg.obj=resource;
handler.sendMessage(msg);//发送消息
}
} catch (Exception e) {
e.printStackTrace();
Message msg=Message.obtain();
msg.what=3;
msg.obj=resource;
handler.sendMessage(msg);//发送消息
}
};
}.start();
}
}
10.今日总结
[1]网页源码查看器
httpurlconnection
服务器是以流的形式把数据返回
[2]消息机制
handler 当想在子线程更新ui的时候需要使用到handler
[3]图片查看器
bitmapFactory 里面都是静态方法 可以把一个流转换成bitmap
[4]runOnUiThread()
[5]新闻客户端(包括前三天大多数知识点)
【注意】java.net.UnknownHostException: www.baidu.com:可能是没加网络权限
【xml解析】如果是XmlPullParser.TEXT,就用getText(),别的都是nextText()(即下个类型是TEXT,就用nextText())
case XmlPullParser.START_TAG://解析开始节点
if("title".equals(parser.getName())){
news.setTitle(parser.nextText());
}
【注意】生成/data/data/com.itheima.cachefiledir/cache/info.txt文件,权限是-rw-------
File file=new File(getCacheDir(),"info.txt");
FileOutputStream fos=new FileOutputStream(file);
fos.write("heheh".getBytes());
fos.close();
【注意】生成/data/data/com.itheima.cachefiledir/files/infoo.txt文件,权限是-rw-rw----,现在是private模式,还有别的模式让其他用户可读或可写
FileOutputStream fos=openFileOutput("info.txt", 0);
fos.write("haha".getBytes());
fos.close();
【加密】Base64.encodeToString(path.getBytes(), Base64.DEFAULT)