Android基础3

一、内容观察者的运行原理

运行过程通常为A应用对内容提供者暴露的数据进行修改,而B应用负则专门责监听内容提供者数据的变化。

1、简单的小演示

首先在内容提供者写一个MyContentProvider类继承ContentProvider如下

public class MyContentProvider extends ContentProvider

继承后会自动重写6个方法(增删改查onCreat和getBytes)在B应用对应修改的方法(增删改)中发出通知,getContext().getContentResolver().notifyChange(uri, null);

通知A应用(观察者内容发生变化),A应用的

Uri uri=Uri.parse("content://qjq");

getContentResolver().query(uri, null, null, null, null);

Log.i(TAG, "查询已完成");

//监听数据的改变。参数二notifyForDescendents boolean  是否级联

getContentResolver().registerContentObserver(uri, true, new MyContentObserver(new Handler()));

Log.i(TAG, "已经设置了监听");}

private class MyContentObserver extends ContentObserver{}//重写构造函数和onChange方法

二、使用内容观察者监听短信数据的改变(掌握)

短信的数据存放的位置,

源码的清单文件里面

短信的存放的位置

核心的URI

代码:

二、短信监听器

getContentResolver().registerContentObserver(Uri.parse("content://sms"), true, new MyContentObserver(new Handler()));MyContentObserver为自己new的一个类继承ContentObserver重写onChange方法代码如下

public void onChange(boolean selfChange) {

// TODO Auto-generated method stub

super.onChange(selfChange);

//如果短信内容改变  方法会被系统自动调用

//获取最新的那条短信  (查询短信数据   需要权限  读短信的权限)

//address 号码  ,body 内容

Cursor c = getContentResolver().query(Uri.parse("content://sms"), new String[]{"address","body"}, null, null, "_id desc");

c.moveToFirst();

String address=c.getString(0);

String body=c.getString(1);

Log.i(TAG, "address:"+address+",body:"+body);

c.close();     }

三、ANR异常(即用户点击按钮5秒没响应的时候西永就会弹出窗口)了解

写一个anr按钮

在mainactivity里面写代码如下

注意以后不能再activity里面不能执行耗时的操作,如果出现耗时的操作,应该开线程

Android的程序默认是单线程即为主线程或者是UI线程。

如何开启线程

开线程有两种方式

第一种方式

new Thread(){

public void run() {

};

}.start();

第二方式

new Thread(new Runnable() {

@Override

public void run() {

}

}).start();

四、【案例】实现点击开始按钮TextView框里面显示1+...+100的结果的变化过程

1.界面一个编辑框一个按钮

2.Mainactivity代码如下如果不使用消息处理器会报错误

07-13 02:38:25.215: E/AndroidRuntime(21713): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.只有主线程才可以操作显示

Mainactivity代码如下:

public class MainActivity extends Activity {

protected static final int UPDATE_SUM = 0;//只是一种标示

private TextView tv_number;

//消息处理器

public Handler mHandler = new Handler() {

//处理消息的方法,输入handle按提示alt+/就可出来

public void handleMessage(android.os.Message msg) {

switch (msg.what) {

case UPDATE_SUM:

int sum = (Integer) msg.obj;

tv_number.setText(sum + "");

break;

default:

break;

}

};

};

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

tv_number = (TextView) findViewById(R.id.tv_number);

}

public void add(View v) {

new Thread() {

public void run() {

int i = 0;

int sum = 0;

while (i <= 100) {

i++;

sum += i;

//tv_number.setText(sum+"");  子线程不能操作显示发消息给主线程

/**

* 思路:

* 1 创建消息

* 2 把数据设置给消息对象

* 3 发送消息

*/

Message msg = Message.obtain();//obtain获得,即获取消息

msg.what = UPDATE_SUM;//给消息设置唯一标示

msg.obj = sum;

mHandler.sendMessage(msg);//消息发送后就会交给mHanlder里面的handleMessage()方法

SystemClock.sleep(200);

}

}

}.start();

}

五、Android下消息机制的实现。

1、网络协议

Get请求,数据写在URL的后面,1kb

Post请求数据在实体里面

六、【案例五】网络图片查看器

在Android2.3以下可以直接使用以下代码读取网络图片,2.3以上必须使用消息处理器来处理

try {//多学一招alt+shift+z(x,y是大小写互换)包裹块来try ...catch

String path = et_path.getText().toString();

// 1 包装网络路径  URL注意不是Uri

URL url=new URL(path);

// 2 打开连接 url.openConnection()

HttpURLConnection conn=(HttpURLConnection) url.openConnection();

//3 设置连接的参数 (超时时长、请求的方式)

conn.setConnectTimeout(10000);

conn.setRequestMethod("get");//小写是错的注意了改成GET

//4 判断响应码:200成功

if (conn.getResponseCode()==200){

//5 获取服务器回送的流数据

InputStream is= conn.getInputStream();

//把流处理成一张图片  再显示

Bitmap bitmap=BitmapFactory.decodeStream(is);

//设置图片显示

iv.setImageBitmap(bitmap);

}

使用消息处理器以及缓存图片全部代码如下

public class MainActivity extends Activity {

private final static String TAG = "MainActivity";

protected static final int SUCCESS_GET_IMAGE = 0;

protected static final int ERROR_GET_IMAGE = 1;

private ImageView iv;

private EditText et_path;

private Handler mHandler = new Handler(){

public void handleMessage(android.os.Message msg) {

switch (msg.what) {

case SUCCESS_GET_IMAGE:

File file = (File) msg.obj;

//设置图片的显示

iv.setImageURI(Uri.fromFile(file));

break;

case ERROR_GET_IMAGE:

Toast.makeText(getApplicationContext(), "获取图片失败", 0).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);

iv = (ImageView) findViewById(R.id.iv);

}

public void get(View v){

new Thread(){

public void run() {

try {

String path = et_path.getText().toString();

File file = new File(Environment.getExternalStorageDirectory(),getFileName(path));

//判断图片是否存在

if(file.exists()){

//直接使用

Log.i(TAG, "使用了缓存的图片");

Message msg = Message.obtain();

msg.what = SUCCESS_GET_IMAGE;

msg.obj = file;

mHandler.sendMessage(msg);

}else{

//1 包装网络路径  URL

URL url = new URL(path);

//2 打开连接 url.openConnection()

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

//超时时长

conn.setConnectTimeout(5000);

//请求的方式

conn.setRequestMethod("GET");

//4 判断响应码:200成功

if(conn.getResponseCode() == 200){

//5 获取服务器回送的流数据

InputStream is = conn.getInputStream();

//把流处理成一张图片  再显示

Bitmap bitmap = BitmapFactory.decodeStream(is);//使用位图工厂处理为图片

//缓存在sdcard

FileOutputStream stream = new FileOutputStream(file);

//format 图片的格式

//quality 图片的质量

//stream 输出流

bitmap.compress(CompressFormat.JPEG, 100, stream);

Log.i(TAG, "下载了图片,并且缓存到了sdcard");

//发消息给主线程

Message msg = Message.obtain();

msg.what = SUCCESS_GET_IMAGE;

msg.obj = file;

mHandler.sendMessage(msg);

}else{

Message msg = Message.obtain();

msg.what = ERROR_GET_IMAGE;

mHandler.sendMessage(msg);

}

}

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

Message msg = Message.obtain();

msg.what = ERROR_GET_IMAGE;

mHandler.sendMessage(msg);

}

};

}.start();

}

//获取文件的名字

public String getFileName(String path){

return path.substring(path.lastIndexOf("/")+1);

}

@Override

public boolean onCreateOptionsMenu(Menu menu) {

// Inflate the menu; this adds items to the action bar if it is present.

getMenuInflater().inflate(R.menu.activity_main, menu);

return true;

}

}

3.使用SmartImageView 开源空间获取网页图片,将loopj.android.image包复制到src目录下另外布局里面的标签要改成loopj.android.image.SmartImageView即包名加上SmartImageView

iv.setImageUrl("http://10.0.2.2:8080/tomcat.png");

七、从服务器上获取json数据

InputStream is = conn.getInputStream();//其实是一个json格式的字符串

//如何把json格式的字符串 转化为对象集合

//1 把流变为字符串

//2 把字符串变为JSONArray

ByteArrayOutputStream bos = new ByteArrayOutputStream();

byte[] buffer = new byte[1024];

int len = 0;

while((len = is.read(buffer)) != -1){

bos.write(buffer, 0, len);

}

String json = bos.toString();

bos.close();

is.close();

//2 把字符串变为JSONArray

JSONArray array = new JSONArray(json);

for(int i = 0;i<array.length();i++){

JSONObject jsonObject = array.getJSONObject(i);

int id = jsonObject.getInt("id");

String name = jsonObject.getString("name");

int age = jsonObject.getInt("age");

Log.i(TAG, "id:"+id+",name:"+name+",age:"+age);

Android基础3

时间: 2024-08-27 02:09:52

Android基础3的相关文章

Android基础入门教程——10.12 传感器专题(3)——加速度-陀螺仪传感器

Android基础入门教程--10.12 传感器专题(3)--加速度/陀螺仪传感器 标签(空格分隔): Android基础入门教程 本节引言: 本节继续来扣Android中的传感器,本节带来的是加速度传感器(Accelerometer sensor)以及 陀螺仪传感器(Gyroscope sensor),和上一节的方向传感器一样有着x,y,z 三个轴, 还是要说一点:x,y轴的坐标要和绘图那里的x,y轴区分开来!传感器的是以左下角 为原点的!x向右,y向上!好的,带着我们的套路来学本节的传感器吧

Android基础入门教程——8.1.3 Android中的13种Drawable小结 Part 3

Android基础入门教程--8.1.3 Android中的13种Drawable小结 Part 3 标签(空格分隔): Android基础入门教程 本节引言: 本节我们来把剩下的四种Drawable也学完,他们分别是: LayerDrawable,TransitionDrawable,LevelListDrawable和StateListDrawable, 依旧贴下13种Drawable的导图: 1.LayerDrawable 层图形对象,包含一个Drawable数组,然后按照数组对应的顺序来

Android基础入门教程——8.1.2 Android中的13种Drawable小结 Part 2

Android基础入门教程--8.1.2 Android中的13种Drawable小结 Part 2 标签(空格分隔): Android基础入门教程 本节引言: 本节我们继续来学习Android中的Drawable资源,上一节我们学习了: ColorDrawable:NinePatchDrawable: ShapeDrawable:GradientDrawable!这四个Drawable~ 而本节我们继续来学习接下来的五个Drawable,他们分别是: BitmapDrawable:Insert

Android基础入门教程——2.3.12 Date &amp; Time组件(下)

Android基础入门教程--2.3.12 Date & Time组件(下) 标签(空格分隔): Android基础入门教程 本节引言: 本节我们来继续学习Android系统给我们提供的几个原生的Date & Time组件,他们分别是: DatePicker(日期选择器),TimePicker(时间选择器),CalendarView(日期视图),好吧, 其实一开始让我扣这几个玩意我是拒绝的,因为在我的印象里,他们是这样的: 简直把我丑哭了,有木有,终于知道为什么那么多人喜欢自定义这种类型的

Android基础入门教程——2.1 View与ViewGroup的概念

Android基础入门教程--2.1 View与ViewGroup的概念 标签(空格分隔): Android基础入门教程 本节引言: 告别了第一章,迎来第二章--Android中的UI(User Interface)组件的详解, 而本节我们要学习的是所有控件的父类View和ViewGroup类!突发奇想,直接翻译官方文档对 这两个东西的介绍吧,对了,天朝原因,google上不去,Android developer上不去,我们可以 改hosts或者用vpn代理,当然也可以像笔者一样使用国内的API

2015年最新Android基础入门教程目录(完结版)

2015年最新Android基础入门教程目录(完结版) 标签(空格分隔): Android基础入门教程 前言: 关于<2015年最新Android基础入门教程目录>终于在今天落下了帷幕,全套教程 共148节已编写完毕,附上目录,关于教程的由来,笔者的情况和自学心得,资源分享 以及一些疑问等可戳:<2015最新Android基础入门教程>完结散花~ 下面是本系列教程的完整目录: 第一章:环境搭建与开发相关(已完结 10/10) Android基础入门教程--1.1 背景相关与系统架构

《2015最新Android基础入门教程》完结散花~

<2015最新Android基础入门教程>完结散花~ 标签(空格分隔): 反思小结 引言: 从六月底就开始编写这套教程,历时将近五个多月,今天终于写完了,全套教程正文部分148篇, 十大章,从基本UI控件到四大组件,Intent,Fragment,事件处理,数据存储,网络编程,绘图与动画, 多媒体,系统服务等都进行了详细的讲解!代码都是都是在Android Studio上进行编写的,全文 采用Markdown,行文结构清晰,还结合了实际开发中一些常见的问题进行了剖析-由于个人能力的局限, 虽然

Android基础入门教程——10.10 传感器专题(1)——相关介绍

Android基础入门教程--10.10 传感器专题(1)--相关介绍 标签(空格分隔): Android基础入门教程 1.传感器相关介绍: 说到传感器,相信大家都不会陌生吧,比如微信的摇一摇就用到了加速度传感器: 传感器的定义:一种物理设备或者生物器官,能够探测.感受外界的信号,物理条件(如光,热, 适度)或化学组成(如烟雾),并将探知的信息传递给其他的设备或者器官! 传感器的种类:可以从不同的角度对传感器进行划分,转换原理(传感器工作的基本物理或化学 效应):用途:输出信号以及制作材料和工艺

Android基础入门教程——8.3.16 Canvas API详解(Part 1)

Android基础入门教程--8.3.16 Canvas API详解(Part 1) 标签(空格分隔): Android基础入门教程 本节引言: 前面我们花了13小节详细地讲解了Android中Paint类大部分常用的API,本节开始我们来讲解 Canvas(画板)的一些常用API,我们在Android基础入门教程--8.3.1 三个绘图工具类详解 中已经列出了我们可供调用的一些方法,我们分下类: drawXxx方法族:以一定的坐标值在当前画图区域画图,另外图层会叠加, 即后面绘画的图层会覆盖前

Android基础入门教程——8.3.11 Paint API之—— ColorFilter(颜色过滤器)(3-3)

Android基础入门教程--8.3.11 Paint API之-- ColorFilter(颜色过滤器)(3-3) 标签(空格分隔): Android基础入门教程 本节引言: 嗯,本来说好今天不写的,还是写吧,毕竟难得空闲哈~,本节给大家带来的是 ColorFilter的第三个子类:PorterDuffColorFilter,看到PorterDuff大家一定不会 陌生吧,假如你看过前面的 Android基础入门教程--8.3.5 Paint API之-- Xfermode与PorterDuff