android心得

来源:互联网 发布:淘宝爆款打造教程 编辑:程序博客网 时间:2024/06/08 07:56
1.Android中Activity的生命周期包含了onPause()和onStop(),关于Activity的生命周期的说明:

启动Activity:系统会先调用onCreate方法,然后调用onStart方法,
最后调用onResume,Activity进入运行状态。
当前Activity被其他Activity覆盖其上或被锁屏:系统会调用onPause方法,暂停当前Activity的执行。
当前Activity
由被覆盖状态回到前台或解锁屏:系统会调用onResume方法,再次进入运行状态。
当前Activity转到新的Activity界面或按Home键回到主屏,自身退居后台:系统会
先调用onPause方法,然后调用onStop方法,进入停滞状态。
用户后退回到此Activity:系统会先调用onRestart方法,然后调用onStart方法,最后调用onResume方法,
再次进入运行状态。
当前Activity处于被覆盖状态或者后台不可见状态,即第2步和第4步,系统内存不足,杀死当前Activity,而后用户退回当前Activity:再次调用onCreate方法、
onStart方法、onResume方法,进入运行状态。
用户退出当前Activity:系统先调用onPause方法,然后调用onStop方法,最后调用onDestory方法,结束当前Activity。




2.屏幕连点自定义n次就触发的监听,可以用监听两次点击的System.currentTimeMillis()的差值,来设定连点的时间间隔,用于判定连点了几次
3.设置定时任务步骤:(设置重复性定时任务也是一样的)
a.设定Intent
b.设定PendingIntent p=PendingIntent.getBroadcast();
c.设定触发具体时间Calendar calendar = Calendar.getInstance();
d.定时:AlarmManager am;am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), p);
4.简单的图片适应屏幕的展示:
a.获取图片的Bitmap bitmap = BitmapFactory.decodeStream(inputs);或者根据图片绝对路径名称
b.获取当前展示面板的分辨率数值,图片保持实际比例和像素的时候需要的高度和宽度,然后获取对应的需要保留的margin,当然margin要大于等于0:
int w2 = mSurfaceViewHeight * bitmap.getWidth()/ bitmap.getHeight();
int h2 = mSurfaceViewWidth * bitmap.getHeight()/bitmap.getWidth() ;
int marginH = (mSurfaceViewWidth - w2) / 2;
int marginW = (mSurfaceViewHeight - h2) / 2;
c.合理设置容器的margin值(此处sv是一个SurfaceView,是图片的展示容器):LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
float be = (float)mSurfaceViewHeight/mSurfaceViewWidth;
float be2 =(float) bitmap.getHeight()/bitmap.getWidth();
if(be>=be2){//图像比较宽,横屏满屏
lp.setMargins(0, marginH, 0, marginH);
}
else lp.setMargins(marginW, 0, marginW, 0);//图像比较窄,竖屏满
sv.setLayoutParams(lp);
5.在Canvas上画图:
a.锁定之后才能画图 SurfaceHolder mSurfaceHolder = sv.getHolder();
Canvas canvas = mSurfaceHolder.lockCanvas();
b.利用Bitmap在Canvas上画图并设定合适的缩放比例
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
paint.setAlpha(255);// 设置透明度
Matrix matrix = new Matrix();
canvas.drawBitmap(bitmap, matrix, paint);
c.解锁画布、释放Bitmap
mSurfaceHolder.unlockCanvasAndPost(canvas);
if (bitmap != null) {
bitmap.recycle();
}
6.mediaplayer播放视频/或者音频.
a.创建MediaPlayer对象new MediaPlayer()
b.设置音频流、数据源、播放容器,准备播放,设置setOnPreparedListener准备好监听,当准备好播放时start()开始播放
c.可以用seekTo(毫秒)的方式跳转到指定时间点播放,可以设置setOnCompletionListener当播放完成后执行的代码。调用release()函数可以释放相关的mediaplayer对象资源.




7.使用com.google.gson.Gson来解析json字符串数组(如果是单个无中括号json,则直接跳过JsonArray和遍历的部分即可),并存入到SharedPreferences的login.xml文件中。此处LoginInfo是和json字段一直的自定义的javabean。
Gson gson = new Gson();
JsonArray jsonArray = JsonUtil.strToJson(sb.toString());
// 遍历JsonArray对象
LoginInfo info = null;
Iterator<JsonElement> it = jsonArray.iterator();
SharedPreferences.Editor editor = context.getSharedPreferences(
"login", Activity.MODE_PRIVATE).edit();// SharedPreferences.Editor
while (it.hasNext()) {
JsonElement e = (JsonElement) it.next();
// JsonElement转换为JavaBean对象
info = gson.fromJson(e, LoginInfo.class);
// 用putString的方法保存数据
editor.putString(info.getId(), info.getPassword() + "/"
+ info.getType());
}
editor.commit();
其中JsonUtil.strToJson()是这样定义的:
public static  JsonArray strToJson(String jsonStr) {
// 创建一个JsonParser
JsonParser parser = new JsonParser();
// 通过JsonParser对象可以把json格式的字符串解析成一个JsonElement对象
JsonElement el = parser.parse(jsonStr);
// 把JsonElement对象转换成JsonArray
JsonArray jsonArray = null;
if (el.isJsonArray()) {
jsonArray = el.getAsJsonArray();
}
return jsonArray;
}
8.获取指定路径下、指定文件后缀名的文件列表files:
File file = new File(MainActivity.VEDIOPATH);//指定路径
File[] files = file.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
boolean ret = name.endsWith(".mp4");
return ret;
}
};);
9.获取图片和视频文件的缩略图供用户浏览,其中视频的kind参数可以是MediaStore.Images.Thumbnails.FULL_SCREEN_KIND:
/**
* 根据指定的图像路径和大小来获取缩略图 此方法有两点好处: 1.
* 使用较小的内存空间,第一次获取的bitmap实际上为null,只是为了读取宽度和高度,
* 第二次读取的bitmap是根据比例压缩过的图像,第三次读取的bitmap是所要的缩略图。 2.
* 缩略图对于原图像来讲没有拉伸,这里使用了2.2版本的新工具ThumbnailUtils,使 用这个工具生成的图像不会被拉伸。

* @param imagePath
*            图像的路径
* @param width
*            指定输出图像的宽度
* @param height
*            指定输出图像的高度
* @return 生成的缩略图
*/
private Bitmap getImageThumbnail(String imagePath, int width, int height) {
Bitmap bitmap = null;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
// 获取这个图片的宽和高,注意此处的bitmap为null
bitmap = BitmapFactory.decodeFile(imagePath, options);
options.inJustDecodeBounds = false; // 设为 false
// 计算缩放比
int h = options.outHeight;
int w = options.outWidth;
int beWidth = w / width;
int beHeight = h / height;
int be = 1;
if (beWidth < beHeight) {
be = beWidth;
} else {
be = beHeight;
}
if (be <= 0) {
be = 1;
}
options.inSampleSize = be;
// 重新读入图片,读取缩放后的bitmap,注意这次要把options.inJustDecodeBounds 设为 false
bitmap = BitmapFactory.decodeFile(imagePath, options);
// 利用ThumbnailUtils来创建缩略图,这里要指定要缩放哪个Bitmap对象
bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height,
ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
return bitmap;
}


/**
* 获取视频的缩略图 先通过ThumbnailUtils来创建一个视频的缩略图,然后再利用ThumbnailUtils来生成指定大小的缩略图。
* 如果想要的缩略图的宽和高都小于MICRO_KIND,则类型要使用MICRO_KIND作为kind的值,这样会节省内存。

* @param videoPath
*            视频的路径
* @param width
*            指定输出视频缩略图的宽度
* @param height
*            指定输出视频缩略图的高度度
* @param kind
*            参照MediaStore.Images.Thumbnails类中的常量MINI_KIND和MICRO_KIND。
*            其中,MINI_KIND: 512 x 384,MICRO_KIND: 96 x 96
* @return 指定大小的视频缩略图
*/
private Bitmap getVideoThumbnail(String videoPath, int width, int height,
int kind) {
Bitmap bitmap = null;

// 获取视频的缩略图
bitmap = ThumbnailUtils.createVideoThumbnail(videoPath, kind);

if(bitmap==null){
//将drawable资源转换为bitmap对象
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.default_slt);
}

System.out.println("w" + bitmap.getWidth());
System.out.println("h" + bitmap.getHeight());
bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height,
ThumbnailUtils.OPTIONS_RECYCLE_INPUT);

return bitmap;
}
10.和服务器交互的设计思路和线程的设计:
a.由于通信方式不是用的socket又要求实时交互,所以设计了心跳接口不断请求服务器,根据服务器返回的010串来判定是否有其它内容需要请求服务器,当然服务器更改相关内容,会将相关位置置1。这样可以避免所有线程都不断请求服务器更新内容的弊端
可以导入封装网络连接的第三方xUtils.jar包,使用其封装好的类执行相关操作,
HttpUtils httpUtils = new HttpUtils(1000).configCurrentHttpCacheExpiry(100);// 设置缓存0.1秒,0.1秒内直接返回上次成功请求的结果。
// 开始进行心跳的长连接
httpUtils.send(HttpMethod.GET, url, callerBack);
RequestCallBack<String> callerBack = new RequestCallBack<String>() {
@Override
public void onSuccess(ResponseInfo<String> responseInfo) {
//获取成功,根据结果执行相关更新线程,获取的数据形式可以是json等形式的
}
@Override
public void onFailure(HttpException error, String msg) {
// throw new RuntimeException("conntect fail ...");
LogUtil.e("HeartbeatCallBack", "心跳失败");
}
};
不断的请求服务器可以用TimerTask实现timertask.schedule(new TimeTask(){//重写run方法}, 延时毫秒, 重复请求间隔);


b.需要重复执行的线程,且想控制其消亡的线程的run()方法可以这样写(单次线程run完后会自动销毁,所以只需要让线程对象的isRun=false即可销毁重复线程,注意线程run方法中也可以使用isRun=false来结束当前执行):
public void run() {
while (isRun) {
try {
// 图片切换动画
drawImg(MainActivity.IMGPATH + fileArr[i]);
Thread.sleep(IMG_SWITCH_INTERVAL * 1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
11.自定义静态LogUtil,复写Log的所有方法,上线后不希望打印那么多Log,只需要将isDebug置false即可.eg:
private static boolean isDebug = true;
public static void e(String tag,String  msg){
if(isDebug){
Log.e(tag, msg);
}
}
12.对于服务器ip可能变化的程序,其应该是可以在程序中修改服务器ip的,这些信息可以保存到xml中。本地只需要根据本地文件的ip执行即可。其它的规则性质文件也可以保存到本地,只需这些文件和服务器保持同步,客户端按照本地文件执行程序即可.
还有合理的使用try{}catch(){}防止系统未初始化或者得到错误数据格式的时候直接程序崩溃.
13.android和服务器交互的接口应该定义到静态类的静态常量里,统一管理,对于用户可以在服务器定义的常量应该存储到sharedpreference中,并且在合适的时机同步这些文件,而客户端只需要根据本地的配置文件执行程序即可。
1 0