欢迎来到千学网!
您现在的位置:首页 > 实用文 > 其他范文

Android中传感器Sensor的使用

时间:2022-06-02 01:45:46 其他范文 收藏本文 下载本文

下面是小编为大家推荐的Android中传感器Sensor的使用,本文共9篇,欢迎大家分享。

Android中传感器Sensor的使用

篇1:Android中传感器Sensor的使用

1.Sensor类型

Android中有多种传感器,目前Android SDK支持的传感器有:光线传感器,旋转向量传感器,压力传感器,陀螺仪传感器,加速度传感器,重力传感器,方向传感器,磁场传感器,近程传感器等,但并不是所有手机都具有全部传感器,一般高端手机具有大多数传感器,毕竟传感器都需要money的,价格自然不菲。

2.Sensor实际应用

那么在Android开发中,如何使用传感器,将传感器功能添加到Android应用中呢,例如微信的摇一摇,通过加速传感器,触发寻找附近的人;例如每次接听电话时,当手机靠近耳朵时,手机会黑屏,这就是光线传感器起作用。

3.Sensor使用步骤

获取传感器管理对象SensorManager

创建传感器事件接听器的类,该类必须实现android.hardware.SensorEventListner接口

使用SensorManager.registerListener方法注册指定的传感器

4.传感器事件接口

SensorEventListner接口,该接口的onSensorChanged和onAccuracyChanged()方法用于处理相应的传感器事件

1 public interface SensorEventListener {

2

3  //传感数据变化调用

4  public void onSensorChanged(SensorEvent event);

5  //传感器精准度变化时调用

6  public void onAccuracyChanged(Sensor sensor, int accuracy);

7 }

5.简单代码实现

定义SensorManager

1 SensorManager sensorManager=(SensorManager) getSystemService(SENSOR_SERVICE);

定义一个匿名内部类或者定义一个类实现SensorEventListner接口

1 private SensorEventListener sensorEventListener=new SensorEventListener() {

2

3    @Override

4    public void onSensorChanged(SensorEvent event) {

5

6       float[] values=event.values;

7       float x = values[0];

8       float y = values[1];

9       float z = values[2];

10    }

11    @Override

12    public void onAccuracyChanged(Sensor sensor, int accuracy) {

13

14    }

15  };

注册和关闭传感器监听事件

@Override

protected void onResume() {

super.onResume();

if(sensorManager!=null){

sensorManager.registerListener(sensorEventListener, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);

}

}

@Override

protected void onPause() {

super.onPause();

if(sensorManager!=null){

sensorManager.unregisterListener(sensorEventListener);

}

}

篇2:android环境传感器

环境传感器

Android平台提供了4个传感器,用于检测不同的外部环境,我们可以使用这些传感器检测周围。例如,可以检测周围空气的湿度、光线、空气的压强和温度。这4个传感器都是基于硬件的传感器。除了光线传感器外,其他3个传感器在普通的Android设备中很少见。所以如果使用环境传感器,最好运行时对当前Android设备所支持的传感器是否检测。

大多数动作传感器和位置传感器都返回多个值,而所有的环境传感器都只返回一个值(SensorEvent.values[0])。例如温度传感器返回摄氏度(°C)、压力传感器返回压强值(hPa)。还有就是环境传感器返回的值很少收到杂音的干扰,而动作和位置传感器经常需要消除杂音的影响。例如,加速度传感器要消除重力对其回传值的影响。

TYPE_AMBIENT_TEMPERATURE :event.values[0] °C

TYPE_LIGHT:event.values[0] lx

TYPE_PRESSURE:event.values[0] hPa

TYPE_RELATIVE_HUMIDITY :event.values[0] RH(%)

// 最强的光线强度(估计只有沙漠地带才能达到这个值)

public static final float LIGHT_SUNLIGHT_MAX = 10.0f;

// 万里无云时阳光直射的强度

public static final float LIGHT_SUNLIGHT = 110000.0f;

// 有阳光,但被云彩抵消了部分光线时的强度

public static final float LIGHT_SHADE = 20000.0f;

// 多云时的光线强度

public static final float LIGHT_OVERCAST = 10000.0f;

// 太阳刚刚升起时(日出)的光线强度

public static final float LIGHT_SUNRISE = 400.0f;

// 在阴雨天,没有太阳时的光线强度

public static final float LIGHT_CLOUDY = 100.0f;

// 夜晚有月亮时的光线强度

public static final float LIGHT_FULLMOON = 0.25f;

// 夜晚没有月亮时的光线强度(当然,也不能有路灯,就是漆黑一片)

public static final float LIGHT_NO_MOON = 0.001f;

篇3:android位置传感器

Android平台提供了两个传感器用于确定设备的位置,这两个传感器是磁场传感器和方向传感器,Android平台还提供了测量设备正面到某一个邻近物体距离的传感器(邻近传感器)。磁场传感器和邻近传感器是基于硬件的传感器。大多数Android手机和平板电脑都有磁场传感器。而邻近传感器通常在手机中很常见。因为可以用该传感器测试接听电话时手机屏幕离脸有多远。可以可以在贴近耳朵接听电话时完成某些工作。方向传感器是基于软件的,该传感器的回传数据来自加速度传感器和磁场传感器。

位置传感器对于确定设备在真实世界中的物理位置非常有用。例如,可以组合磁场传感器和加速度传感器测量设备相对于地磁北极的位置,还可以利用方向传感器确定当前设备相对于自身参照系的位置。

磁场传感器和方向传感器都返回值3个值(SensorEvent.values),而邻近传感器只返回1个值。

方向传感器:

SensorEvent.values[0]:

绕着Z轴旋转的角度。如果Y轴(正常拿手机的方向)正对着北方,该值是0,如果Y轴指向南方,改值是180,Y轴指向东方,该值是90,如果Y轴指向西方,该值是270,

SensorEvent.values[1]:

绕着X轴旋转的度数。当从Z轴正方向朝向Y轴正方向,改值为正值。反之,为负值。该值在180至-180之间变动。

SensorEvent.values[2]:

绕着Y轴旋转的度数。当从Z轴正方向朝向X轴正方向,改值为正值。反之,为负值。该值在180至-180之间变动。

磁场传感器:

SensorEvent.values[0]:

沿着X轴的磁力(μT,millitesla)

SensorEvent.values[1]:

沿着Y轴的磁力(μT,millitesla)

SensorEvent.values[2]:

沿着Z轴的磁力(μT,millitesla)

邻近传感器:

SensorEvent.values[0]:

手机正面距离邻近物理的距离(CM)

具体代码和上一篇的一样我就不写了

篇4:Android中AsyncTask使用

一、AsyncTask的作用:

代替Thread+Handler的组合,使创建异步任务变得简单,

AsyncTask执行后台操作,并在用户界面上发布结果,而不必处理线程。

二、AsyncTask的定义:

public abstract class AsyncTask

extends Object

AsyncTask必须子类可以使用。子类将覆盖至少一个方法(doInBackground执行异步任务),通常会覆盖一次(onPostExecute显示结果,更新UI)

AsyncTask三种类型如下:

》Params,参数的类型发送到任务执行时。

》Progress,在后台计算过程中公布的进度单元类型。

》Result,计算结果的类型。

不是所有类型都是异步任务所使用的。要标记为未使用的类型,设置该类型Void:

三、AsyncTask的方法:

1、onPreExecute

在任务开始后立即调用,在UI线程执行。这一步通常用于设置任务,例如在用户界面中初始化进度条。

2、doInBackground(Params...)

后台线程调用onPreExecute()完成后立即执行。这一步后台进程执行,可能会花费很长时间。

3、onProgressUpdate(Progress...)

调用publishProgress,在UI线程上执行,

这种方法是用来显示用户进度界面,后台进程仍在执行。例如,它可用于显示一个进度条或在文本中显示日志。

4、onPostExecute(Result)

后台进程处理完后,在UI线程上执行。后台进程的结果被传递到这一步作为参数。

常用的写法如下:

class MyTask extends AsyncTask { @Override protected String doInBackground(String... params) { //执行异步任务 int n = 10; //调用publishProgress公布进度,最后onProgressUpdate方法将被执行 publishProgress(n); Thread.sleep(500);return null; } @Override protected void onPostExecute(String result) { //更新UI,显示结果 } @Override protected void onProgressUpdate(Integer... values) { //更新进度信息 }

new MyTask().execute();//执行任务

三、AsyncTask的规则:

1、任务实例必须在用户界面线程中创建。

2、execute(Params... params)方法必须在UI线程中调用。

3、不要手动调用onPreExecute,doInBackground,onProgressUpdate,onPostExecute这些方法

4、一个任务实例只能执行一次,如果执行第二次将会抛出异常

篇5:Android中各种drawable的使用

其实这些个drawable的使用并不难,也不需要去哪里百度或者Google找答案,直接自己试验一下即可,

如:ic-launcher图标具体大小是多少,如有的人把一张512 x 512的图片当成ic-launcher,在高分辨率手机上没有问题,但是在一些低分辨率手机上发现桌面上找不到自己应用的图标,或者显示名称但看不到图标,想找ic-launcher标准大小吗?创建一个Android项目不就有了吗?看系统生成的那些ic-launcher在各种drawable上的大小即可,这就是最标准的了,何需百度,出图标的时候就让美工按着那些图标大小出就不会有问题了。

又如,通知栏图标要多大呢?如果大小不合适,则显示通知的时候看到的图标可能显示不全或者其它问题,要想知道通知栏图标多大合适,找Android系统设计的那些呀,路径为:sdkplatformsandroid-15data es,在这里搜索notification,然后看看相同名字的通知栏图标在不同的drawable中的大小是多少,这样你就知道你应该让美工给你切多大的通知栏图标了^_^

接下来了解本质的东西,下面的内容都是我拿真实手机测试出来的结果,所以应该比百度出来的那些更有真实性。

一般手机的分辨率对应的各参数为:

drawable-ldpi 文件夹: 低密度屏幕:dpi = 120dp,scale = ??, 超级元老,不用管它,不会再有这种dpi的手机的啦!drawable-mdpi 文件夹: 中等密度屏 幕:dpi = 160dp,scale = 1.0,分辨率:320 x 480drawable-hdpi 文件夹: 高密度屏幕:dpi = 240dp,scale = 1.5,分辨率:480 x 854drawable-xhdpi 文件夹: 超高密度屏幕:dpi = 320dp,scale = 2.0,分辨率:720 x 1280drawable-xxhdpi文件夹: 超超高密度屏幕:dpi = 480dp,scale= 3.0,分辨率:1080 x 1920

scale 为缩放系数,标准的dpi是160dpi,所以160dpi的scale为1.0,其它dpi的缩放系数都是与160相比算出来的,如320dpi,它除以160dpi结果为2,所以320dpi的scale为2.0

好,有了这个scale之后呢创建图片就简单了,怎么个简单法?先找出160dpi对应的大小就OK了,

如,美工设计了一张很美的图片,而且是以720 x 1080的分辨率为基础进行设计,假如宽高都为300像素,则这张图放在720 x1280的手机上显示肯定是完美的,如果放到其它分辨就有可能会被压缩或者放大,那效果就会大打折扣,所以我们大家都知道要切多套图片放到不同的drawable目录中,那问题来了,美工如果她不懂,她问你,其它分辨率怎么切图?

怎么切呢?我们就先算出160dpi对应的大小就行了,它切的图是以720 x 1080的手机为基础设计的,这个分辨率对应的是xhdpi,scale是2.0,所以160dpi对应的大小就是:300 / 2.0 = 150像素,那这样的话4种drawable的图片怎么切就有答案了:

160dpi 的图片大小为150像素,那其它的就按scale去算就好了,如下:drawable-hdpi: 150* 1.5 = 225drawable-xhdpi: 150 *2.0 = 300drawable-xxhdpi: 150 *3.0 = 450

就目前情况来说,切图切4套就够了。

假如,有一张图片,你并不知道它是在哪个分辨率的基础上进行设计的,那你就不知道这张图片应该放在哪个drawable文件夹中,这种情况经常会遇到,比如我们学习Android时的那些图片,根本不知道是谁设计的,也不知道是在哪个分辨率的基础上设计的,那你怎么知道放在哪个drawable文件夹中比较合适呢?一般人会选择放在drawable-hdpi 文件夹中,或许吧,多人这么做肯定是这样做一般没什么问题,但是,同一张图片,注:只有一张图片哦,把它放到不同的drawable文件夹中,然后在同一台手机上的显示效果会不一样哦,为什么会这样呢?嗯,夜已深,我先睡觉,有时间再来写完它。。。

篇6:android sqlite 使用

Android操作系统使用SQLite数据库,使用有两种方法获得数据库对象:

1.获取已经存在的数据库

?

1

SQLiteDatabase dbbrndi=SQLiteDatabase.openDatabase(“/sdcard/zhycheng.db3”, null,SQLiteDatabase.OPEN_READONLY);

第一个String参数是数据库在文件系统中的位置,第二个参数一般为null,第三个参数控制数据库打开的方式,

这样就获得了数据库对象。

2.自己创建数据库

新建一个类,继承SQLiteOpenHelper,添加未实现的方法

代码如下

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

package your.zhycheng;

import android.content.Context;

import android.database.sqlite.SQLiteDatabase;

import android.database.sqlite.SQLiteDatabase.CursorFactory;

import android.database.sqlite.SQLiteOpenHelper;

public class MyHelper extends SQLiteOpenHelper{

public MyHelper(Context context, String name)

{

this(context,name,1);

}

public MyHelper(Context context, String name,int version)

{

this(context,name,null,version);

}

public MyHelper(Context context, String name,//数据库的名字

CursorFactory factory,

int version) {

super(context, name, factory, version);

}

@Override

public void onCreate(SQLiteDatabase db) {

db.execSQL(“create table user(id int,name text)”);

}

@Override

public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

}

}

获得的数据库位于/data/data/yourpackage/databases/zhycheng.db3

然后通过生成一个MyHelper类的对象,调用

?

1

2

3

MyHelper mh=new MyHelper(this,“zhycheng”);

SQLiteDatabase db=mh.getReadableDatabase;

SQLiteDatabase db=mh.getWritableDatabase();

分别获得只读和可写的数据库,

获得数据库之后就可以进行数据库操作有以下两种方式操作数据库

1.执行SQL语句

?

1

2

3

db.rawQuery(sql,Args)

db.execSQL(sql, Args)

db.execSQL(sql)

上面的sql是String类型的数据库语言,Args是String数组。前面String中若有“?”则对应后面的值。

篇7:策略模式在android中使用

策略模式(Strategy)

策略模式是对象的行为模式,它的用意是针对一组算法,将每一个算法封装到具有共同接口的独立类中,从而使得它们可以相互替换。策略模式使得算法可以在不修改或影响到调用端的情况下发生变化。

下面来讨论下策略模式的结构类图,具体如下:

从上面的结构图中,我们可以看出策略模式涉及到了三个角色,具体角色如下所示:

A、抽象策略角色:这是个抽象角色,通常是由一个接口或是抽象类来实现。它为所有的具体策略类提供了需要的接口。

B、具体策略角色:这个角色包装了相关的算法和行为,用来执行对应的策略事件。

C、环境角色:这个角色中含有一个对抽象策略类的引用,也是供外部调用直接接触的角色。

下面具体举个例子来使用策略模式。例子是这样的:现在要做一个上网使用得app,接入的网络类型有三种,分别为CMCC、ChinaNet及普通的Wifi类型,所以针对这几种类型的网络,我们需要定义一个抽象的策略角色,然后再定义三个具体角色,每个具体的角色中实现具体的功能细节,最后,我们在前端放置三个按钮,点击对应的按钮调用对应的具体角色逻辑(通过调用抽象角色)。下面为我的代码逻辑实现以及部分说明文字:

抽象策略角色(WifiConnectStrategy):

/**

* 抽象策略角色

*/

public abstract classWifiConnectStrategyimplementsCallback{

privateWifiConnectStrategyListener listener =null;

protectedWifiState wifiState =null;

protectedHandler handler =null;

protected static final longCONN_WIFI_TIME= ; // 连接wifi的时间(模拟)

publicWifiConnectStrategy() {

handler =newHandler(WifiConnectStrategy.this);

}

public voidsetWifiConnectStrategyListener(WifiConnectStrategyListener listener) {

this.listener = listener;

}

/**

* 创建一个策略,根据wifitype

*/

public staticWifiConnectStrategycreateWithWifiType(WifiType wifiType) {

WifiConnectStrategy result =null;

switch(wifiType) {

caseCMCC:

result =newCMCCWifiConnectStrategy();

break;

caseCHINANET:

result =newChinaNetWifiConnectStrategy();

break;

caseCOMMON:

result =newCommonWifiConnectStrategy();

break;

default:

break;

}

returnresult;

}

public voidconfigWifiState(WifiState wifiState) {

this.wifiState = wifiState;

}

/**

* 连接到网络的方法

*/

public abstract voidexecuteConnectNetRun();

/**

* 模拟链接后返回的结果

*/

public abstract voidconnectResult();

// 模拟网络链接延迟

protected voidsimulateConnect() {

this.handler.removeMessages(1);

this.handler.sendEmptyMessageDelayed(1,CONN_WIFI_TIME);

}

@Override

public booleanhandleMessage(Message msg) {

connectResult();

return true;

}

publicWifiConnectStrategyListener getListener() {

returnlistener;

}

public voidsetListener(WifiConnectStrategyListener listener) {

this.listener = listener;

}

public voidlog(String log) {

Log.d(WifiConnectStrategy, log);

}

}

具体策略角色(CMCC):

/**

* 具体策略角色

*/

public classCMCCWifiConnectStrategyextendsWifiConnectStrategy {

publicCMCCWifiConnectStrategy() {

super();

}

@Override

public voidexecuteConnectNetRun() {

log(cmcc connect ...);

// 链接网络核心代码(异步)

//TODO

// 模拟网络链接延迟

simulateConnect();

}

@Override

public voidconnectResult(){

getListener().cmccConnResult(this.wifiState.getWifiLabel() +连接成功!);

}

}

具体策略角色(ChinaNet):

public classChinaNetWifiConnectStrategyextendsWifiConnectStrategy {

publicChinaNetWifiConnectStrategy() {

super();

}

@Override

public voidexecuteConnectNetRun() {

log(chinanet connect ...);

// 链接网络核心代码

//TODO

// 模拟网络链接延迟

simulateConnect();

}

@Override

public voidconnectResult(){

getListener().cmccConnResult(this.wifiState.getWifiLabel() +连接成功!);

}

}

具体策略角色(Common wifi):

public classCommonWifiConnectStrategyextendsWifiConnectStrategy {

publicCommonWifiConnectStrategy() {

super();

}

@Override

public voidexecuteConnectNetRun(){

log(common connect ...);

// 链接网络核心代码

//TODO

// 模拟网络链接延迟

simulateConnect();

}

@Override

public voidconnectResult(){

getListener().cmccConnResult(this.wifiState.getWifiLabel() +连接成功!);

}

}

下面为我们具体的环境角色,主要就是引用一个抽象策略角色,以及根据不同网络类型创建对应的具体策略角色,具体如下:

public classMainActivityextendsActivityimplementsOnClickListener {

privateButton btnCmcc =null;

privateButton btnChinanet =null;

privateButton btnCommon =null;

privateWifiConnectStrategy wifiConnectStrategy;

privateWifiState selectedState =newWifiState();

privateWifiConnectStrategyListener listener =newWifiConnectStrategyListener() {

@Override

public voidcmccConnResult(String state) {

log(state);

}

@Override

public voidchinanetConnResult(Stringstate) {

log(state);

}

@Override

public voidcommonConnResult(String state) {

log(state);

}

};

@Override

protected voidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

btnCmcc = (Button) findViewById(R.id.btnCmcc);

btnChinanet = (Button) findViewById(R.id.btnChinanet);

btnCommon = (Button) findViewById(R.id.btnCommon);

btnCmcc.setOnClickListener(this);

btnChinanet.setOnClickListener(this);

btnCommon.setOnClickListener(this);

}

@Override

public voidonClick(View v) {

if(null!= wifiConnectStrategy) {

wifiConnectStrategy =null;

}

if(v.getId() == R.id.btnCmcc) {

selectedState.setCardNo(cmcc+1167278922);

selectedState.setIpAddress(192168013);

selectedState.setPassword(123456);

selectedState.setWifiLabel(CMCC);

selectedState.setSsid(dafadfdadada);

selectedState.setWifiType(WifiType.CMCC);

wifiConnSpecial(selectedState);

}

else if(v.getId() == R.id.btnChinanet) {

selectedState.setCardNo(cmcc+1167272222);

selectedState.setIpAddress(192168433);

selectedState.setPassword(123456777);

selectedState.setWifiLabel(ChinaNet);

selectedState.setSsid(dafadeeeedada);

selectedState.setWifiType(WifiType.CHINANET);

wifiConnSpecial(selectedState);

}

else{

selectedState.setIpAddress(192168111);

selectedState.setPassword(123456789);

selectedState.setWifiLabel(COMMON);

selectedState.setSsid(dafadeeeSSDASF);

selectedState.setWifiType(WifiType.COMMON);

wifiConnCommon(selectedState);

}

}

private voidwifiConnSpecial(WifiState wifiState) {

wifiConnectStrategy = WifiConnectStrategy.createWithWifiType(selectedState.getWifiType());

wifiConnectStrategy.configWifiState(wifiState);

wifiConnectStrategy.setWifiConnectStrategyListener(listener);

wifiConnectStrategy.executeConnectNetRun();

}

private voidwifiConnCommon(WifiState wifiState) {

wifiConnectStrategy = WifiConnectStrategy.createWithWifiType(selectedState.getWifiType());

wifiConnectStrategy.configWifiState(wifiState);

wifiConnectStrategy.setWifiConnectStrategyListener(listener);

wifiConnectStrategy.executeConnectNetRun();

}

private voidlog(String log) {

Log.d(WifiConnectStrategy,log);

}

}

注意:这里的WifiState类为wifi的封装类,WifiConnectStrategyListener为监听网络链接的接口,

接下来,我会在下面罗列出他们的代码构成。

WifiState:

public classWifiState {

//wifiname

privateString wifiLabel;

//wifi ip

private intipAddress;

//wifi ssid

privateString ssid;

//wifipassword

privateString password;

// card no

privateString cardNo;

// 类型

privateWifiType wifiType;

//wifi类型

public enumWifiType {

CMCC(1),

CHINANET(2),

COMMON(3);

private final inttype;

privateWifiType(inttype) {

this.type = type;

}

public intgetType() {

returntype;

}

public staticWifiTypegetType(intwifiType) {

WifiTypetype =null;

if(WifiType.CMCC.getType() == wifiType) {

type = WifiType.CMCC;

}

else if(WifiType.CHINANET.getType() == wifiType) {

type = WifiType.CHINANET;

}

else if(WifiType.COMMON.getType() == wifiType) {

type = WifiType.COMMON;

}

returntype;

}

}

public intgetIpAddress() {

returnipAddress;

}

public voidsetIpAddress(intipAddress) {

this.ipAddress = ipAddress;

}

publicString getSsid() {

returnssid;

}

public voidsetSsid(String ssid) {

this.ssid = ssid;

}

publicString getPassword() {

returnpassword;

}

public voidsetPassword(String password) {

this.password = password;

}

publicString getCardNo() {

returncardNo;

}

public voidsetCardNo(StringcardNo) {

this.cardNo = cardNo;

}

publicString getWifiLabel() {

returnwifiLabel;

}

public voidsetWifiLabel(String wifiLabel) {

this.wifiLabel = wifiLabel;

}

publicWifiType getWifiType() {

returnwifiType;

}

public voidsetWifiType(WifiType wifiType) {

this.wifiType = wifiType;

}

}

WifiConnectStrategyListener:

/**

*wifi链接的监听

*/

public interfaceWifiConnectStrategyListener {

public voidcmccConnResult(String state);

public voidchinanetConnResult(String state);

public voidcommonConnResult(String state);

}

好了,运行下代码,页面效果如下:

当我们点击对应的按钮链接网络时,会在输出日志打印对应的wifi链接以及链接成功,当然,这是只是模拟实现,实际上整个过程没这么简单,比如需要先获得卡号,然后异步链接,获得返回的信息,链接是否成功等。

日志如下:

好了,到这里,策略模式的介绍就完成了,稍后会把项目代码上传,希望对大家有帮助。

篇8:观察者模式在android中使用

观察者模式(Observer)

观察者模式是对象的行为模式,又被叫做为模型-视图模式,这种模式定义了一种一对多的依赖关系,使多个观察者对象同时监听某个角色对象。一旦这个角色对象的状态发生了变化,就会通知所有观察者对象,使它们能够自动更新自己本身。

下面来看下观察者模式的结构,具体如下:

从上面图中可以看出,观察者模式涉及了四个角色,具体如下所示:

A、抽象实体角色:这个角色为抽象角色,它把所有的对观察者对象的引用都保存在一个聚集中,每个主题对象都可以有若干个观察者对象,主题角色又叫做抽象被观察者对象,一般用抽象类或接口表示。

同时,这个角色中含有了对观察者具体的管理方法及当主题角色发生改变时通知所有观察者对象。

B、具体实体角色:这个角色为具体实现了抽象的实体角色的具体角色。它含有了一个对实体角色状态的引用,一但实体角色改变,那么就会调用通知方法通知所有观察者对象。

C、抽象观察者对象:这个角色为所有的具体的观察者对象提供通用的接口,在得到实体变化的通知时实时的更新自己,这个角色一般用抽象类和接口来实现。

D、具体观察者对象:将有关的状态放到具体观察者对象中,在具体主题的内部的状态改变时,给所有的观察者发送通知。该角色又叫做为具体被观察者角色。

下面具体举例来说明观察者模式的使用。例子是这样的:用户现在要购买若干件同一品牌的不同款式的衣服,假如用户已经选好了不同款式的衣服,现需要实现添加到购物车并支付;支付成功之后,现在需要及时刷新用户的购物车,以便用户可以及时知道自己支付的结果,方便从新支付或挑选其他款式并支付。好了,具体需要描述完了,接下来请看功能详细类图说明:

下面直接看代码吧!我会在下面列出观察者模式的核心代码,其他请参看我上传的项目代码包,具体如下:

抽象实体角色(Cart):

/**

*@description:

* 抽象实体角色-观察者关注的对象实体

*/

public abstract classCart {

privateVectorobservers =newVector;

publicCart() {

super();

}

/**

*@description:

* 登记一个观察者对象

*/

public voidattach(SalesObserver observer) {

observers.addElement(observer);

}

/**

*@description:

* 删除一个已经登记的观察者对象

*/

public voiddetach(SalesObserver observer) {

observers.removeElement(observer);

}

public voiddetach(intindex) {

observers.remove(index);

}

/**

*@description:

* 通知所有已经登记过的观察者对象

*/

public voidnotifyAllBills(){

Enumerationenumes = observers();

while(enumes.hasMoreElements()){

SalesObserverobj = (SalesObserver)enumes.nextElement();

obj.updateSale(obj);

}

}

/**

*@description:

* 支付成功之后,更新购物车内的所有商品的支付状态

* 注意:这里更新的是本地缓存数据(不通过接口更新)

*/

public booleanbillsPay() {

booleanpayStatus =true;

// 异步网络支付

//TODO

// 这里模拟支付成功

if(payStatus) {

// 更新本地缓存数据

updateLocalCache();

}

return true;

}

/**

*@description:

* 更新缓存

*/

private voidupdateLocalCache() {

for(SalesObserver obs : observers) {

Salesale = obs.getSale();

sale.setPayStatus(支付完成);

}

}

publicEnumerationobservers() {

returnobservers.elements();

}

}

具体实体角色(ShoppingCart):

/**

*@description:

* 具体的实体角色-具体通知各个观察者对象更新状态

*/

public classShoppingCartextendsCart {

publicShoppingCart() {

super();

}

protected voidbillPayResult(booleanflag) {

if(!flag) {

// 支付失败提示(这里不考虑这种情况)

return;

}

// notifyobervers

notifyAllBills();

}

}

抽象观察者角色(Observer):

/**

*@description:

* 抽象观察者-为所有具体观察者提供更新方法

*/

public interfaceObserver{

publicObject updateSale(Object obj);

}

具体观察者角色(SalesObserver):

/**

*@description:

* 具体观察者-具体执行更改状态的操作

*/

public classSalesObserverimplementsObserver {

privateSale sale =null;

publicSalesObserver(Sale sale) {

this.sale = sale;

}

@Override

publicObject updateSale(Object obj) {

this.sale = (Sale) obj;

returnsale;

}

publicSale getSale() {

returnsale;

}

public voidsetSale(Sale sale) {

this.sale = sale;

}

}

好了,核心的代码已经贴上了,下面会列出整个流程的演示效果图:

添加购物车:

移除购物车:

支付之后效果(之前购物车和移除购物车效果相同略):

篇9:适配器模式在android中使用

适配器模式(Adapter):

适配器模式是一种行为模式,它可以把一个类的接口转换成为另一个所期待的另一种接口,这样可以使原本因接口无法在一起工作的两个类能够在一起工作了,适配器模式有类的适配器和对象的适配器两种形式,这里只介绍对象的适配器模式(与类适配器模式类似),下面为类的适配器(左)和对象适配器模式(右)的简略类图结构:

适配器模式所涉及的角色有适配角色、目标角色和适配器角色,具体描述如下:

适配角色:提供需要适配转换的接口角色。

目标角色:调用者所期待的接口。

适配器角色:把适配角色转为目标角色的接口。

与之前一样,我们同样列举一个实例来说明适配器模式的使用。在电商平台中,查询商品、查看商品详情、添加购物车和支付是最常见不过了。假如原系统中已经实现了商品的查询、添加购物车以及支付功能,查询功能包括查询商品、查看详情、以及计算商品总价;添加购物车包括查看详情、商品添加购物车以及支付,目前这两个模块功能是不协同工作的,所以下面我们将会把购物车适配成为可以与查看商品一起工作,实现他们的一体化操作。那么他们的详细结构类图如下所示:

好了,下面罗列下适配器模式的核心代码。

目标角色(SaleShopCenter):

/**

*@description:

* 目标对象

*/

public interfaceSaleShopCenter {

ListscanSaleItems(String pKey);

SalescanSaleDetail(String pId);

doublecalculateTotalPrice();

}

适配角色(ShoppingCart):

/**

*@description:

* 适配的对象

*/

public classShoppingCart {

privateSalesale =null;

public staticListresults=null; // 模拟缓存数据ß

publicSale scanSaleDetail(StringpId) {

// 异步请求网络

//TODO

// 这里模拟实现

sale = getSale(pId);

returnsale;

}

public voidaddSaleShoppingCart(Listsales) {

// 异步请求网络

//TODO

addCart(sales);

}

public booleanbillPay(Listsales) {

// 异步请求网络

//TODO

// 这里模拟支付成功

booleanpayStatus =true;

if(null==SaleShoppingManager.results

||0 > SaleShoppingManager.results.size()) {

payStatus =false;

}

returnpayStatus;

}

privateSale getSale(StringpId) {

if(null==SaleShoppingManager.results

||0 > SaleShoppingManager.results.size()) {

return null;

}

Salesale =null;

for(Saleitem : SaleShoppingManager.results) {

if(item.getpID().equals(pId)) {

sale = item;

}

}

returnsale;

}

private voidaddCart(Listsales) {

results= sales;

}

}

适配器角色(SaleShoppingManager):

/**

*@description:

* 适配器对象角色

*/

public classSaleShoppingManagerimplementsSaleShopCenter {

privateShoppingCartcart =null;

public staticListresults=null; // 模拟缓存数据

publicSaleShoppingManager() {

cart =newShoppingCart();

}

@Override

publicListscanSaleItems(StringpKey) {

results=newArrayList();

// 异步网络请求

//TODO

// 这里模拟实现

results= getSales();

returnresults;

}

@Override

publicSale scanSaleDetail(StringpId) {

returncart.scanSaleDetail(pId);

}

@Override

public doublecalculateTotalPrice() {

if(null==results|| 0 >results.size()) {

return0;

}

doubletotalPrice = 0;

for(Salesale :results) {

totalPrice += sale.getpPrice();

}

returntotalPrice;

}

privateListgetSales() {

Listresult =newArrayList();

Salesale =newSale();

sale.setpID(0000121300);

sale.setbID(1111232300);

sale.setpName(衬衫-黑领);

sale.setpPrice(123.14);

sale.setpDescri(黑色、圆领,高端大气!);

result.add(sale);

Salesale2 =newSale();

sale2.setpID(0000121311);

sale2.setbID(1111232311);

sale2.setpName(衬衫-黑领);

sale2.setpPrice(123.34);

sale2.setpDescri(黑色、圆领,高端大气!);

result.add(sale2);

Salesale3 =newSale();

sale3.setpID(0000121322);

sale3.setbID(1111232322);

sale3.setpName(衬衫-黑领22);

sale3.setpPrice(123.24);

sale3.setpDescri(黑色、圆领,高端大气!);

result.add(sale3);

returnresult;

}

publicShoppingCart getCart() {

returncart;

}

}

下面为程序的运营结果图,后面我会上传项目代码,感兴趣的同学可以下载跑跑,

效果图如下:

好了,到这里适配器模式已经介绍完了。

传感器心得体会

传感器论文

android学习方法

android个人简历

温度传感器论文

教你如何在电脑上使用Android系统网络技巧

android程序员简历

Android程序员简历

Android图像处理技术(实现Android中的PS)

Android中Looper的quit方法和quitSafely方法

《Android中传感器Sensor的使用(精选9篇).doc》
将本文的Word文档下载到电脑,方便收藏和打印
推荐度:
点击下载文档

文档为doc格式

点击下载本文文档