PR中如何利用网格ps调出网格线36个

下次自动登录
现在的位置:
& 综合 & 正文
Android Alarm manager 定时闹钟开发详解
下文出自:http://www.cxy.me/doc/5888.htm
Alarm manager 主要管理硬件时钟。
一些与时间相关的应用,如日历,闹钟等需要使用Alarm Manager的服务。Alarm manager功能相对比较简单,相关位于
frameworks/base/core/jni/server/com_android_server_AlarmManagerService.cpp
frameworks/base/services/java/com/android/server/AlarmManagerService.java
一. frameworks/base/core/jni/server/com_android_server_AlarmManagerService.cpp
这部分代码直接管理硬件时钟,设备名为/dev/alarm。包括打开设备,关闭设备,设置时区,设置触发时间(timeout),以及等待时钟触发。
二. frameworks/base/services/java/com/android/server/AlarmManagerService.java
这部分封装目录一中的代码,向上提供java接口,同时与客户端(如calendar)交互,接收来自客户端的时钟设置请求,并在时钟触发时通知客户端。
Alarm是在预定的时间上触发Intent的一种独立的方法。
Alarm超出了应用的作用域,所以它们可以用于触发应用事件或动作,甚至在应用关闭之后。与Broadcast Receiver结合,它们可以变得尤其的强大,可以通过设置Alarm来启动应用或者执行动作,而应用不需要打开或者处于活跃状态。
举个例子,你可以使用Alarm来实现一个闹钟,执行正常的网络查询,或者在“非高峰”时间安排耗时或有代价的操作。
对于仅在应用生命周期内发生的定时操作,Handler类与Timer和Thread类的结合是一个更好的选择,它允许Android更好地控制系统资源。
Android中的Alarm在设备处于睡眠模式时仍保持活跃,它可以设置来唤醒设备;然而,所有的Alarm在设备重启时都会被取消。
Alarm的操作通过AlarmManager来处理,通过getSystemService可以获得其系统服务,如下所示:
AlarmManager alarms = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
为了创建一个新的Alarm,使用set方法并指定一个Alarm类型、触发时间和在Alarm触发时要调用的Intent。如果你设定的Alarm发生在过去,那么,它将立即触发。
这里有4种Alarm类型。你的选择将决定你在set方法中传递的时间值代表什么,是特定的时间或者是时间流逝:
? RTC_WAKEUP
在指定的时刻(设置Alarm的时候),唤醒设备来触发Intent。
在一个显式的时间触发Intent,但不唤醒设备。
? ELAPSED_REALTIME
从设备启动后,如果流逝的时间达到总时间,那么触发Intent,但不唤醒设备。流逝的时间包括设备睡眠的任何时间。注意一点的是,时间流逝的计算点是自从它最后一次启动算起。
? ELAPSED_REALTIME_WAKEUP
从设备启动后,达到流逝的总时间后,如果需要将唤醒设备并触发Intent。
Alarm的创建过程演示如下片段所示:
int alarmType = AlarmManager.ELAPSED_REALTIME_WAKEUP;
long timeOrLengthofWait = 10000;
String ALARM_ACTION = “ALARM_ACTION”;
Intent intentToFire = new Intent(ALARM_ACTION);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intentToFire, 0);
alarms.set(alarmType, timeOrLengthofWait, pendingIntent);
当Alarm到达时,你指定的PendingIntent将被触发。设置另外一个Alarm并使用相同的PendingIntent来替代之前存在的Alarm。
取消一个Alarm,调用AlarmManager的cancel方法,传入你不再希望被触发的PendingIntent,如下面的代码所示:
alarms.cancel(pendingIntent);
接下来的代码片段中,设置了两个Alarm,随后马上取消了第一个Alarm。第一个Alarm显式地设置了在特定的时间唤醒设备并发送Intent。第二个设置为从设备启动后,流逝时间为30分钟,到达时间后如果设备在睡眠状态也不会唤醒它。
AlarmManager alarms = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
String MY_RTC_ALARM = “MY_RTC_ALARM”;
String ALARM_ACTION = “MY_ELAPSED_ALARM”;
PendingIntent rtcIntent = PendingIntent.getBroadcast(this, 0, new Intent(MY_RTC_ALARM), 1);
PendingIntent elapsedIntent = PendingIntent.getBroadcast(this, 0, new Intent(ALARM_ACTION), 1);
// Wakeup and fire intent in 5 hours.(注释可能有错)
Date t = new Date();
t.setTime(java.lang.System.currentTimeMillis() + 60*1000*5);
alarms.set(AlarmManager.RTC_WAKEUP, t.getTime(), rtcIntent);
// Fire intent in 30 mins if already awake.
alarms.set(AlarmManager.ELAPSED_REALTIME, 30*60*1000, elapsedIntent);
// Cancel the first alarm.
alarms.cancel(rtcIntent);
下文出自:/melaniedeng/archive//2355066.html
关于android自动关机,网上有很多应用和例子。 相对于自动开机来说,自动关机可以在应用层通过设置alarm来实现。而自动开机,网上的介绍就比较少了,因为它需要底层rtc时钟的支持。前段时间根据客户需求实现了自动开关机。在这里分享一下。
我的实现是在设置程序里面增加一个接口,让用户设置自动开关机,这个自动开关机的设置可以参照闹钟的设置。关于自动关机,考虑到关机的时候,用户可能正有一些重要的操作,那么应该给用户一个机会去取消当前的关机。
1)一个BroadcastReceiver, 接收如下信息:
  a) 自定义的ACTION_REQUEST_POWER_OFF:设置auto power off时,通过AlarmManager设置的一个RTC_WAKEUP时钟。当到设置的关机时间时,之前设置到AlarmManager的这个action会被广播。我们实现的这个BroadcastReceiver接收到这个消息后,就要开始power off流程
  b) 自定义的ACTION_REQUEST_POWER_ON:设置auto power on时,通过AlarmManager设置的一个RTC_WAKEUP时钟。我们知道power on的应该设置一个rtc的alarm,那么这个RTC_WAKEUP的alarm是做什么的呢?其实当用户设置自动关机的时候,我设置了2个时钟,一个是RTC时钟,用于关机状态下开机;还有一个就是这个RTC_WAKEUP时钟。之所以设置这个时钟,其实是这样的,比如说你设置了周一到周五每天7点半自动开机,而周四早上你7点就打开了手机,这样到7点半的时候,之前设置的时钟就过期了,如果不重新设置的话,周五早上是不会自动开机的。所以这个时候,之前设置的RTC_WAKEUP就接收到了这样的信息,在重新设置下次自动开机的时钟。
  c) BOOT_COMPLETE和TIMEZONE changed, Time set等时间相关的action:当系统开机完成或时间、时区发生改变时,都需要重新设置alarm。
2)一个处理power off 的Service,当BroadcastReceiver接收到ACTION_REQUEST_POWER_OFF,我们给用户一个机会去取消当前的自动关机。这个Service的作用就是启动一个无背景的页面,给用户提示。同时播放之前用户设置的提示音或振动。
3)一个Activity:显示一个dialog提示用户要自动关机,并用一个计时器倒计时。当用户确认关机,或者计时器到时间的时候,就关机。否则取消当前关机,并重设下次自动关机alarm。
2. 自动关机的实现。自动关机的实现比较简单,这里主要说一下怎么设置alarm,和实现关机:
1) 设置自动关机的alarm:
AlarmManager am = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(
"com.android.settings.action.REQUEST_POWER_OFF");
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,
intent, PendingIntent.FLAG_CANCEL_CURRENT);
am = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, time, pendingIntent);
2)自动关机掉的是./frameworks/base/services/java/com/android/server/ShutdownActivity.java:
Intent newIntent = new Intent(Intent.ACTION_REQUEST_SHUTDOWN);
newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(newIntent);
Intent.ACTION_REQUEST_SHUTDOWN是Intent里面一个隐藏的action。
3. 自动开机的实现。一直在做上层应用和framework,对于底层不是很熟悉。正好有同事之前做过关机闹铃,所以把他之前的实现稍加改动就可以了。在系统power off的状态下自动开机,我们需要设置一个rtc时钟,当用户设置自动开机时,由AlarmManagerService将时钟设置下去。这学要底层的支持。这里的实现是定义一个我们自己的rtc alarm type:
1) 首先要在头文件里面定义:
  a) kernel/include/linux/android_alarm.h
#define ANDROID_ALARM_GET_TIME(type)
ALARM_IOW(4, type, struct timespec)
#define ANDROID_ALARM_SET_RTC
_IOW('a', 5, struct timespec)
/* we define ANDROID_RTC_ALARM_SET for auto power off */
#define ANDROID_RTC_ALARM_SET
_IOW('a', 7, int)
#define ANDROID_ALARM_BASE_CMD(cmd)
(cmd & ~(_IOC(0, 0, 0xf0, 0)))
  b) bionic/libc/kernel/common/linux/android_alarm.h
#define ANDROID_RTC_ALARM_SET _IOW('a', 7, int)
2) 定义完成之后,还需要实现:在kernel/drivers/rtc/alarm-dev.c文件的alarm_ioctl方法里面,增加一个case,实现设置alarm
case ANDROID_RTC_ALARM_SET:
unsigned int rtc_alarm_
struct rtc_time rtc_
if (copy_from_user(&rtc_alarm_time, (void __user *)arg,
sizeof(rtc_alarm_time))) {
rv = -EFAULT;
goto err1;
if (pmic_rtc_get_time(&rtc_now) & <span style="color:#) {
rtc_now.sec = <span style="color:#;
if (pmic_rtc_start(&rtc_now) & <span style="color:#) {
printk("get and set rtc info failed\n");
pmic_rtc_disable_alarm(PM_RTC_ALARM_1);
rtc_now.sec += rtc_alarm_
pmic_rtc_enable_alarm(PM_RTC_ALARM_1, &rtc_now);
当然不要忘记增加一个include:
#include &mach/pmic.h&
3)在frameworks/base/services/jni/com_android_server_AlarmManagerService.cpp里面增加一个方法去设置时钟:
static void android_server_AlarmManagerService_updateRtcAlarm(JNIEnv* env, jobject obj, jint fd, jint seconds)
#if HAVE_ANDROID_OS
int result = ioctl(fd, ANDROID_RTC_ALARM_SET, &seconds);
LOGE("set rtc alarm to %d later: %s\n", seconds, strerror(errno));
if (result & <span style="color:#)
LOGE("Unable to set rtc alarm to %d later: %s\n", seconds, strerror(errno));
还有就是不要忘记定义一下接口:
{"updateRtcAlarm", "(II)V", (void*)android_server_AlarmManagerService_updateRtcAlarm},
4) 在frameworks/base/services/java/com/android/server/AlarmManagerService.java里面定义native的设置alarm的方法,然后调用就可以实现将自动关机的alarm设置下去了:
定义:private native void updateRtcAlarm(int fd, int seconds);
public void setRepeating(int type, long triggerAtTime, long interval,
PendingIntent operation) {
if (operation == null) {
Slog.w(TAG, "set/setRepeating ignored because there is no intent");
synchronized (mLock) {
Alarm alarm = new Alarm();
alarm.type =
alarm.when = triggerAtT
alarm.repeatInterval =
alarm.operation =
// Remove this alarm if already scheduled.
removeLocked(operation);
if (localLOGV) Slog.v(TAG, "set: " + alarm);
int index = addAlarmLocked(alarm);
if (index == 0) {
setLocked(alarm);
// Start to setup auto power on alarm
if ((alarm.type == AlarmManager.ELAPSED_REALTIME_WAKEUP) &&
alarm.operation.getTargetPackage().equals("com.android.settings")) {
updateRtcAlarm(mDescriptor, (int)((alarm.when - System.currentTimeMillis()) / 1000));
// End to setup auto power on alarm
5)在应用层设置自动开机
AlarmManager am = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(
"com.android.settings.action.REQUEST_POWER_ON");
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,
intent, PendingIntent.FLAG_CANCEL_CURRENT);
am = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, time, pendingIntent);
1) 自动开机原理比较简单,但是需要底层的支持,所以对于做应用或者framework层的技术人员来说,实现起来稍微比较麻烦。
2) 在设置自动开关机的时候,需要考虑的情况很多,比如是否设置时间/时区的改变,手机当前是开机还是关机状态等。
闹钟代码示例:http://blog.csdn.net/wang_yubin/article/details/8440837
&&&&推荐文章:
【上篇】【下篇】注册广播的方式,区别: 常驻和非常驻,常驻广播当程序退出时还可以接受广播并处理,动态注册的广播可以随时取消。 activity生命周期: create start resume pause stop destroy 界面在start时就可见了,在resume可与用户交互,一般保存数据等操作放在pause方法中。 1.启动Activity:系统会先调用onCreate方法,然后调用onStart方法,最后调用onResume,Activity进入运行状态。 2.当前Activity被其他Activity覆盖其上或被锁屏:系统会调用onPause方法,暂停当前Activity的执行。 3.当前Activity由被覆盖状态回到前台或解锁屏:系统会调用onResume方法,再次进入运行状态。 4.当前Activity转到新的Activity界面或按Home键回到主屏,自身退居后台:系统会先调用onPause方法,然后调用onStop方法,进入停滞状态。 5.用户后退回到此Activity:系统会先调用onRestart方法,然后调用onStart方法,最后调用onResume方法,再次进入运行状态。 6.当前Activity处于被覆盖状态或者后台不可见状态,即第2步和第4步,系统内存不足,杀死当前Activity,而后用户退回当前Activity:再次调用onCreate方法、onStart方法、onResume方法,进入运行状态。 7.用户退出当前Activity:系统先调用onPause方法,然后调用onStop方法,最后调用onDestory方法,结束当前Activity。 综上,当用户点返回键(后退键)返回上一个activity时,onRestart->onResume这里会运行onRestart回调。 Activity的四种启动模式:. standard模式启动模式,每次激活Activity时都会创建Activity,并放入任务栈中。. singleTop如果在任务的栈顶正好存在该Activity的实例, 就重用该实例,否者就会创建新的实例并放入栈顶(即使栈中已经存在该Activity实例,只要不在栈顶,都会创建实例)。. singleTask如果在栈中已经有该Activity的实例,就重用该实例(会调用实例的onNewIntent())。重用时,会让该实例回到栈顶,因此在它上面的实例将会被移除栈。如果栈中不存在该实例,将会创建新的实例放入栈中。 这里注意:如果栈中有activity的实例会将该实例移到栈顶,并将原来其上的实例移除! . singleInstance在一个新栈中创建该Activity实例,并让多个应用共享该栈中的该Activity实例。一旦该模式的Activity的实例存在于某个栈中,任何应用再激活该Activity时都会重用该栈中的实例,其效果相当于多个应用程序共享一个应用, 不管谁激活该Activity都会进入同一个应用中。 一个超级简单的问题啊!android程序的入口是什么?是Application啊!
OOM发生的原因,如何避免:http://my.oschina.net/line926/blog/2711751。应用中加载大的资源对象,如Bitmap,当加载大量高清图片时会出现内存溢出。 解决的方法:当需要显示大的Bitmap或者大量的Bitmap时,需要通过图片压缩来防止OOM,可以通过BitmapFactory.Options的inJustDecodeBounds属性为true,这样的话不会加载图片到内存,但可以读出图片的尺寸,从而进行图片压缩,Options.inSampleSize可以设置压缩比例.2.持有无用的对象到时gc无法回收,导致memory leak: a.静态变量导致没存泄漏, b.不合理的使用Context,通常我们会将context做为参数传递,传递的就可能延长context的生命周期,最终导致内存泄漏。一个简单的例子我们在activity中可能需要将context传递到一个后台的线程或组件中,这时如果屏幕发生的旋转,显然这个activity是无法回收的,这样就势必导致内存泄漏。所以使用context时需要考虑context的生命周期,如果使用该context的组件生命周期超过了context的生命周期,可以考虑使用生命周期更长的Application context。如果一定要用到context也可以考虑使用弱引用。3.非静态内部类导致内存溢出, 这里记住一句话,非静态内部类隐式含有外部类的引用,这一点是导致这种情况内存溢出的关键。如果该内部类的生命周期超出了外部类对象,就像我们定义的匿名内部类Handler、AsyncTask是默认含有外部类Activity 引用的,这里最好使用静态内部类避内存溢出的问题。4.Drawable对象的回调隐含的Memory leak 关于Android中的Bitmap:获取方式: a.从资源中获取:Bitmap rawBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.img1); b.从SD卡中获取:String SDCarePath=Environment.getExternalStorageDirectory().toString();String filePath=SDCarePath+"/"+"haha.jpg";Bitmap rawBitmap1 = BitmapFactory.decodeFile(filePath, null); InputStream inputStream=getBitmapInputStreamFromSDCard("haha.jpg");Bitmap rawBitmap2 = BitmapFactory.decodeStream(inputStream);设置图片的圆角,返回设置后的BitMap: public Bitmap toRoundCorner(Bitmap bitmap, int pixels) {Bitmap roundCornerBitmap = Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(), Config.ARGB_8888);Canvas canvas = new Canvas(roundCornerBitmap);int color = 0xff424242;Paint paint = new Paint();paint.setColor(color);// 防止锯齿paint.setAntiAlias(true);Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());RectF rectF = new RectF(rect);float roundPx =// 相当于清屏canvas.drawARGB(0, 0, 0, 0);// 先画了一个带圆角的矩形canvas.drawRoundRect(rectF, roundPx, roundPx, paint);paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));// 再把原来的bitmap画到现在的bitmap!!!注意这个理解canvas.drawBitmap(bitmap, rect, rect, paint);return roundCornerB }将图片高宽和的大小kB压缩: //得到图片原始的高宽 int rawHeight = rawBitmap.getHeight(); int rawWidth = rawBitmap.getWidth(); // 设定图片新的高宽 int newHeight = 500; int newWidth = 500; // 计算缩放因子 float heightScale = ((float) newHeight) / rawH float widthScale = ((float) newWidth) / rawW // 新建立矩阵 Matrix matrix = new Matrix(); matrix.postScale(heightScale, widthScale); // 设置图片的旋转角度 // matrix.postRotate(-30); // 设置图片的倾斜 // matrix.postSkew(0.1f, 0.1f); // 将图片大小压缩 // 压缩后图片的宽和高以及kB大小均会变化 Bitmap newBitmap = Bitmap.createBitmap(rawBitmap, 0, 0, rawWidth,rawWidth, matrix, true);将Bitmap转换为DrawableDrawable转Bitmap: Drawable newBitmapDrawable = new BitmapDrawable(Bitmap); Bitmap bitmap = newBitmapDrawable.getBitmap();回收Bitmap所占用的内存,避免内存溢出:if(!bitmap.isRecycled()){bitmap.recycle();}
Android ANR: Android中程序响应不灵敏时系统会提示ANR(Application Not Responding)。默认情况下activity的最长执行时间为5秒,broadcastreceiver的最长执行时间为10秒。 系统中ActivityManager和WindowManager会监测应用程序的响应性。如下情况会提示ANR:1.在5秒内没有响应输入的事件。2.broadcastreceiver在10秒内没有执行完。 以上情况可能是在主线程中做了比较耗时的操作,如:网络请求下载、图片处理、io异常等等。 主线程中尽量减少耗时的操作,关键生命周期方法中减少计算耗时处理,如onCreate、onResume。避免在Intent Receiver里启动一个Activity,因为它会创建一个新的画面,并从当前用户正在运行的程序上抢夺焦点。如果你的应用程序在响应Intent广 播时需要向用户展示什么,你应该使用Notification Manager来实现。应用程序应该避免在BroadcastReceiver里做耗时的操作或计算。但不再是在子线程里做这些任务(因为 BroadcastReceiver的生命周期短),替代的是,如果响应Intent广播需要执行一个耗时的动作的话,应用程序应该启动一个 Service。Android屏幕旋转Activity的生命周期: 1.如果配置了:android:configChanges="orientation|keyboardHidden",onCreate->onStart->onResume->onConfigurationChanged->onConfigurationChanged.... 2.如果没有设置上面的属性,则需要重写onSaveInstanceState()和 onRestoreInstanceState()用以保存和恢复数据,onCreate->onStart->onResume->onSaveInstanceState->onPause->onStop->onDestroy->onCreate->onStart->onRestoreInstanceState->onResume context.getCacheDir()获取应用程序自己的缓存路径 context.getExternalCacheDir()获取应用程序在外部存储的存储目录 Android中通过Environment类可以获取外部存储路径,其中的几个常量:MEDIA_BAD_REMOVAL 在没有挂载前存储媒体已经被移除。MEDIA_CHECKING 正在检查存储媒体。MEDIA_MOUNTED 存储媒体已经挂载,并且挂载点可读/写。MEDIA_MOUNTED_READ_ONLY 存储媒体已经挂载,挂载点只读。MEDIA_NOFS 存储媒体是空白或是不支持的文件系统。MEDIA_REMOVED 存储媒体被移除。MEDIA_SHARED 存储媒体正在通过USB共享。MEDIA_UNMOUNTABLE 存储媒体无法挂载。MEDIA_UNMOUNTED 存储媒体没有挂载。通过getExternalStorageState获取外部存储的状态。读写数据必须先判断:if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !Environment.isExternalStorageRemovable())还提供android标准目录的路径: DIRECTORY_ALARMS 系统提醒铃声存放的标准目录。 DIRECTORY_DCIM 相机拍摄照片和视频的标准目录。 DIRECTORY_DOWNLOADS 下载的标准目录。 DIRECTORY_MOVIES 电影存放的标准目录。 DIRECTORY_MUSIC 音乐存放的标准目录。 DIRECTORY_NOTIFICATIONS 系统通知铃声存放的标准目录。 DIRECTORY_PICTURES 图片存放的标准目录 DIRECTORY_PODCASTS 系统广播存放的标准目录。 DIRECTORY_RINGTONES 系统铃声存放的标准目录。几个常用的方法:static File getDataDirectory() 获得data的目录(/data)。static File getDownloadCacheDirectory() 获得下载缓存目录。(/cache)static File getExternalStorageDirectory() 获得外部存储媒体目录。(/mnt/sdcard or /storage/sdcard0)static File getRootDirectory() 获得系统主目录(/system)Android屏幕自适应:http://blog.csdn.net/lmj/article/details/.使用dp(常识),但是dp只能解决大致相同尺寸屏幕的适配问题,对于4.3->5.0是无能为力的。 2.编写多套数值文件。 3.比例,通过weight设置,这里有个限制就是需要依赖LinearLayout。多使用match_parent,其实也是比例的概念。 4.通过自定义View Service与Activity通信方式:http://blog.csdn.net/gebitan505/article/details/ 1.广播交互,通过在service中发送广播,并在相应的组件(Activity)中接受广播来实现数据通信,这里要注意一个内容,就是当我们在接收到广播后需要处理相关数据内容时,如更新、图片处理等耗时操作最好在broadcastreceiver中发送到handler处理(这里广播处理10秒的显示容易忘记)。 2.共享文件交互,这里可以理解为serivce和activity通过同一个文件来进行交互,如最简单的文本文件。在Android中有一个SharedPreferences,通过它也可以实现数据通信。这里需要注意的是读写并发。 3.Messager方式,这个应该是最先想到的方式,下面是一个简单的实例: public class MessengerService extends Service{private static final String TAG = "MYTAG";private static final int TIME = 1;static final int TEST = 0;private int i = 0;private Timer mTimer =private Handler mHandler = new Handler(){ @Override public void handleMessage(Message msg) {super.handleMessage(msg);switch (msg.what) {case TEST: Log.e(TAG, "Get Message from MainActivity."); cMessenger = msg.replyTo;//get the messenger of client mTimer.schedule(new MyTimerTask(), 1000,TIME * 1000);default:} }};private Messenger mMessenger = new Messenger(mHandler);//It's the messenger of serverprivate Messenger cMessenger =//It's the messenger of
IBinder onBind(Intent intent) { Log.i(TAG, "MessengerService.onBind()..."); return mMessenger.getBinder(); void onCreate() { super.onCreate(); Log.i(TAG, "MessengerService.onCreate()...pid: "+Process.myPid()); mTimer = new Timer(); void onDestroy() { super.onDestroy(); Log.i(TAG, "MessengerService.onDestroy()..."); if(mTimer!=null){mTimer.cancel();mTimer = }}class MyTimerTask extends TimerTask { @Override public void run() {if (i == 100) { i = 0;}try { //send the message to the client Message message = Message.obtain(null, MessengerService.TEST,i, 0); cMessenger.send(message);} catch (RemoteException e) { e.printStackTrace();}i++; }} } public class MainActivity extends Activity {private static final String TAG = "MYTAG";private boolean mIsBprivate Button startBtn =private Button stopBtn =private TextView mTextView =private Messenger rMessenger =private Messenger mMessenger =private Intent intent =private ProgressBar mProgressBar =private Handler mHandler = new Handler(){ @Override public void handleMessage(Message msg) {super.handleMessage(msg);switch (msg.what) {case MessengerService.TEST: Log.e(TAG, "Get Message From MessengerService. i= "+msg.arg1); int curLoad = msg.arg1; mTextView.setText(curLoad+"%"); mProgressBar.setProgress(curLoad);
default:} }}; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main);intent = new Intent("com.seven.messagerservice.MessengerService"); mProgressBar = (ProgressBar)findViewById(R.id.myProgressBar); mProgressBar.setMax(100); mTextView = (TextView)findViewById(R.id.loading_Tv); startBtn = (Button)findViewById(R.id.start_Btn); stopBtn = (Button)findViewById(R.id.stop_Btn); startBtn.setOnClickListener(new ButtonClickListener()); stopBtn.setOnClickListener(new ButtonClickListener());}class ButtonClickListener implements OnClickListener { @Override public void onClick(View v) {if (startBtn == v) { Log.i(TAG, "Start Button Clicked.pid: "+Process.myPid()); doBindService();} else if (stopBtn == v) { Log.i(TAG, "Send Button Clicked."); doUnBindService();} }
} @Overrideprotected void onDestroy() { super.onDestroy();} private ServiceConnection serConn = new ServiceConnection()
public void onServiceDisconnected(ComponentName name) {Log.i(TAG, "onServiceDisconnected()...");rMessenger =
public void onServiceConnected(ComponentName name, IBinder service) {Log.i(TAG, "onServiceConnected()..."); rMessenger = new Messenger(service);//get the object of remote service mMessenger = new Messenger(mHandler);//initial the object of local service sendMessage(); }}; private void doBindService(){Log.i(TAG, "doBindService()..."); mIsBind = bindService(intent, serConn, BIND_AUTO_CREATE);//if bind success return true Log.e(TAG, "Is bind: "+mIsBind); } private void doUnBindService(){if(mIsBind){ Log.i(TAG, "doUnBindService()..."); unbindService(serConn); mIsBind =} }
private void sendMessage() { Message msg = Message.obtain(null, MessengerService.TEST);//MessengerService.TEST=0 msg.replyTo = mM try {rMessenger.send(msg); } catch (RemoteException e) {e.printStackTrace(); }} } 4.定义接口方式,这种方式和上面的Messager方式类似,都是通过Connection获取远程实例,这里有一个实例: public interface ICountService {public int getCurrentLoad(); } public class DownLoadService extends Service implements ICountService{private static final String TAG = "MYTAG";private static final int TIME = 1;private Timer timer =private int i = 0;private ServiceBinder serviceBinder = new ServiceBinder();public class ServiceBinder extends Binder implements ICountService{ @Override public int getCurrentLoad() {Log.i(TAG, "ServiceBinder getCurrentLoad()... i=:"+i); }
IBinder onBind(Intent intent) { Log.i(TAG, "DownLoadService.onBind()..."); return serviceB}
@Overridepublic void onCreate() { super.onCreate(); Log.i(TAG, "DownLoadService.onCreate()...pid: "+Process.myPid()); timer = new Timer(); timer.schedule(new MyTimerTask(), 0, TIME*1000);}
@Overridepublic int onStartCommand(Intent intent, int flags, int startId) { Log.i(TAG, "DownLoadService.onStartCommand()..."); Log.e(TAG, "flags: "+flags+" startId: "+startId);return super.onStartCommand(intent, flags, startId);}
@Overridepublic void onDestroy() { super.onDestroy(); Log.i(TAG, "DownLoadService.onDestroy()..."); if(timer!=null){timer.cancel();timer = }}class MyTimerTask extends TimerTask{ @Override public void run() {if(100==i){ i=0;}i++; } }
@Overridepublic int getCurrentLoad() { return 0;} } public class ServiceTestDemo2 extends Activity { private static final String TAG = "MYTAG"; private static final int TIME = 1; private static final int MAX = 100; private Button startSerBtn = private Button stopSerBtn = private TextView currentTv = private Intent intent = private Timer timer = private ProgressBar mProgressBar = private ICountService iCountService = @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main);timer = new Timer(); mProgressBar = (ProgressBar)findViewById(R.id.myProgressBar); mProgressBar.setMax(MAX); intent = new Intent("com.seven.test"); currentTv = (TextView)findViewById(R.id.loading_Tv); startSerBtn = (Button)findViewById(R.id.start_Btn); stopSerBtn = (Button)findViewById(R.id.stop_Btn); startSerBtn.setOnClickListener(new ButtonClickListener()); stopSerBtn.setOnClickListener(new ButtonClickListener()); } @Overrideprotected void onDestroy() { super.onDestroy(); Log.e(TAG, "onDestroy()...pid: "+Process.myPid());}
Handler mHandler = new Handler(){ @Override public void handleMessage(Message msg) {super.handleMessage(msg);Log.i(TAG, "handleMessage...");int curLoad = iCountService.getCurrentLoad();mProgressBar.setProgress(curLoad);currentTv.setText(curLoad+"%"); } }; class MyTimerTask extends TimerTask{ @Override public void run() {mHandler.sendMessage(mHandler.obtainMessage()); } } private ServiceConnection serConn = new ServiceConnection()
public void onServiceDisconnected(ComponentName name) {iCountService =
public void onServiceConnected(ComponentName name, IBinder service) {Log.i(TAG, "onServiceConnected()...");iCountService = (ICountService) }};class ButtonClickListener implements OnClickListener { @Override public void onClick(View v) {if (startSerBtn == v) { Log.i(TAG, "Start Button Clicked."); bindService(intent, serConn, BIND_AUTO_CREATE); timer.schedule(new MyTimerTask(), 1000, TIME * 1000);//这里一定要延迟一下再开始获取数据,不然会报空指针异常} else if (stopSerBtn == v) { Log.i(TAG, "Stop Button Clicked."); unbindService(serConn); if (timer != null) {timer.cancel();timer = }} }} } 5.最后,AIDL方式ListView多种布局实现:/devinzhang/archive//2573554.html   1)重写 getViewTypeCount() – 该方法返回多少个不同的布局   2)重写 getItemViewType(int) – 根据position返回相应的Item   3)根据view item的类型,在getView中创建正确的convertView 实例: public class listViewTest extends Activity {/** Called when the activity is first created. */  ListView listV  MyAdapter listA  ArrayList listS  public void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.main);    listView = (ListView)this.findViewById(R.id.listview);    listString = new ArrayList();    for(int i = 0 ; i < 100 ; i++)    {      listString.add(Integer.toString(i));    }    listAdapter = new MyAdapter(this);    listView.setAdapter(listAdapter);  }  class MyAdapter extends BaseAdapter{    Context mC    LinearLayout linearLayout =    LayoutI    TextV    final int VIEW_TYPE = 3;    final int TYPE_1 = 0;    final int TYPE_2 = 1;    final int TYPE_3 = 2;    public MyAdapter(Context context) {      // TODO Auto-generated constructor stub      mContext =      inflater = LayoutInflater.from(mContext);    }    public int getCount() {      // TODO Auto-generated method stub      return listString.size();    }    //每个convert view都会调用此方法,获得当前所需要的view样式    public int getItemViewType(int position) {      // TODO Auto-generated method stub      int p = position%6;      if(p == 0)        return TYPE_1;      else if(p < 3)        return TYPE_2;      else if(p < 6)        return TYPE_3;      else        return TYPE_1;    }    public int getViewTypeCount() {      // TODO Auto-generated method stub      return 3;    }    public Object getItem(int arg0) {      // TODO Auto-generated method stub      return listString.get(arg0);    }    public long getItemId(int position) {      // TODO Auto-generated method stub          }    public View getView(int position, View convertView, ViewGroup parent) {      // TODO Auto-generated method stub      viewHolder1 holder1 =      viewHolder2 holder2 =      viewHolder3 holder3 =      int type = getItemViewType(position);      //无convertView,需要new出各个控件      if(convertView == null)      {         Log.e("convertView = ", " NULL");        //按当前所需的样式,确定new的布局        switch(type)        {        case TYPE_1:          convertView = inflater.inflate(R.layout.listitem1, parent, false);          holder1 = new viewHolder1();          holder1.textView = (TextView)convertView.findViewById(R.id.textview1);          holder1.checkBox = (CheckBox)convertView.findViewById(R.id.checkbox);          Log.e("convertView = ", "NULL TYPE_1");          convertView.setTag(holder1);                  case TYPE_2:          convertView = inflater.inflate(R.layout.listitem2, parent, false);          holder2 = new viewHolder2();          holder2.textView = (TextView)convertView.findViewById(R.id.textview2);          Log.e("convertView = ", "NULL TYPE_2");          convertView.setTag(holder2);                  case TYPE_3:          convertView = inflater.inflate(R.layout.listitem3, parent, false);          holder3 = new viewHolder3();          holder3.textView = (TextView)convertView.findViewById(R.id.textview3);          holder3.imageView = (ImageView)convertView.findViewById(R.id.imageview);          Log.e("convertView = ", "NULL TYPE_3");          convertView.setTag(holder3);                  }      }else{        //有convertView,按样式,取得不用的布局        switch(type)        {        case TYPE_1:          holder1 = (viewHolder1) convertView.getTag();          Log.e("convertView !!!!!!= ", "NULL TYPE_1");                  case TYPE_2:          holder2 = (viewHolder2) convertView.getTag();          Log.e("convertView !!!!!!= ", "NULL TYPE_2");                  case TYPE_3:          holder3 = (viewHolder3) convertView.getTag();          Log.e("convertView !!!!!!= ", "NULL TYPE_3");                  }      }    //设置资源      switch(type)      {        case TYPE_1:          holder1.textView.setText(Integer.toString(position));          holder1.checkBox.setChecked(true);                  case TYPE_2:          holder2.textView.setText(Integer.toString(position));                  case TYPE_3:          holder3.textView.setText(Integer.toString(position));          holder3.imageView.setBackgroundResource(R.drawable.icon);                }      return convertV    }  }  //各个布局的控件资源  class viewHolder1{    CheckBox checkB    TextView textV  }  class viewHolder2{    TextView textV  }  class viewHolder3{    ImageView imageV    TextView textV  }}ArrayList、LinkedList、Vector,HashMap、HashTable、HashSet的区别。 从存储结构、线程安全、存储和访问特性等方面。 1.Vector是线程安全的,ArrayList不是,所以ArrayList的效率会更高,存储结构上都是顺序数组形式。 2.LinkedList在存储结构上是双向链表的形式,存删易。 3.HashMap实现Map接口,存的是键值对,key和value可为null,HashTable是Dictionary的子类,线程安全。 4.HashSet可以看作是没有key的Map,set从定义上讲是无序不重复结合。xml解析的几种方式: 1.DOM解析,消耗内存,见xml文件全部load memory 使用DOM API来访问树形结构并获取数据,不适合内存有限的移动设备。 2.SAX解析,解析效率高,占用内存少,基于事件驱动。是一个顺序解析的过程,当解析到起始标签或者结束标签是触发相应的事件进行处理,这里不需要将文件全部加载到内存中。 3.Pull解析,事件驱动,可以调用next方法来获取下一个解析事件,当处于某个元素时可以通过XmlPullParser的getAttribute方法获取属性值,通过nextText获取节点值。Java中堆和栈的区别,内存机制: 1.基本数据类型和对象引用都是在栈上分配, 2.堆内存用来存放new创建的对象和数组(c中malloc) 3.类变量(静态变量)是在程序加载时在堆内存中分配内存,将堆内存地址存放在栈中,也就是说静态变量是保存在对内存中的。 4.堆内存中不是连续的空间分配给变量,地址分配通过hash算法,gc回收的地址未必会立即回收。 5.局部变量,如循环中的临时变量是在执行到它时在栈中开辟内存,脱离作用域后立即释放。Assets与raw的区别: Assets可以有子目录,不可以通过资源ID访问,这里有AssetManager来访问assets中的资源。
最新教程周点击榜
微信扫一扫

我要回帖

更多关于 ps网格线怎么调出 的文章

 

随机推荐