1,listview的优化:
2,在Service里面不可以运行耗时的操作,因为Service也是运行在主线程里的.
3 在子线程中弹出Toast
4, 备份短息
5,Looper和Handler
6 ,反编译的步骤
7,PopupWindow
8,判断是否是系统应用程序
9,根据包名和完整类名卸载,启动,分享程序
1,listview的优化:
我们知道listview通过Adapter把数据填充进去的,下面是自定义Adapter的代码片段:
/**
* 返回每个条目对应的view对象
* position 当前item的位置
* convertView 老的view,也就是显示过的item的view
* parent listView
*/
public View getView(int position, View convertView, ViewGroup parent) {
View view;
if (convertView == null) {
view = inflater.inflate(R.layout.applationinstall_item, null);
} else {
view = convertView;
}
}
这样的话就极大的重用 了对象,避免的大量的去创建对象,如果listview一次最多只能显示10条记录,那么一开始就会创建10个View对象,如果往下拉,又会接着创建对象,如果重用了convertView那么往下拉的时候就会使用上一次创建的10个对象.
2,在Service里面不可以运行耗时的操作,因为Service也是运行在主线程里的.
我们可以通过Thread.getCurrentThread().getName()来测试.
3 在子线程中弹出Toast
Looper.prepare();
Toast.makeText(context, "你好", 1).show();
Looper.loop();
4, 备份短息
第一步,获取所有的短信:
ContentResolver resolver = getContentResolver();
infos = new ArrayList<SmsInfo>();
Cursor cursor = resolver.query(Uri.parse("content://sms/"), new String[]{"_id","address","body","date","type"}, null, null, "date desc");
while(cursor.moveToNext()){
//获取短信的时间
SimpleDateFormat dateformater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date(cursor.getLong(cursor.getColumnIndex("date")) );
String datestr = dateformater.format(date);
//获取短信的地址
String address = cursor.getString( cursor.getColumnIndex("address"));
//获取短信正文
String body = cursor.getString( cursor.getColumnIndex("body"));
//获取短信的类型
String messagetype;
int type = cursor.getInt( cursor.getColumnIndex("type"));
//短信的类型:接收的还是发送的
if(type==1){
messagetype = "接受";
}else{
messagetype = "发送";
}
int id = cursor.getInt( cursor.getColumnIndex("_id"));
SmsInfo info = new SmsInfo(id, address, body, datestr, messagetype);
Log.i(TAG,info.toString());
infos.add(info);
}
cursor.close();
第二部,把对象持久化到文件中:
private void save2XML() {
try {
File file = new File(Environment.getExternalStorageDirectory(),"smsback.xml");
FileOutputStream fos = new FileOutputStream(file);
SmsInfoSerializer.save(infos, fos);
//"通知"用户保存文件成功
Notification notification = new Notification(R.drawable.notification, "短信备份完成", System.currentTimeMillis());
//notification.sound= Uri.fromFile( new File("sdcard/xxx.mp3"));
//点击进入主界面
Intent intent = new Intent(BackUpSmsService.this,MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(BackUpSmsService.this, 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK);
notification.setLatestEventInfo(BackUpSmsService.this, "短信备份完毕", "点击进入主界面", pendingIntent);
//把notification显示到界面上
manager.notify(0, notification);
} catch (Exception e) {
Looper.prepare();
Toast.makeText(getApplicationContext(), "生成文件异常", 1).show();
Looper.loop();
e.printStackTrace();
}
}
public static void save(List<SmsInfo> infos, OutputStream os)
throws Exception {
XmlSerializer serializer = Xml.newSerializer();
serializer.setOutput(os, "UTF-8");
serializer.startDocument("UTF-8", true);
serializer.startTag(null, "smss");
for (SmsInfo info : infos) {
serializer.startTag(null, "sms");
serializer.attribute(null, "id", info.getId() + "");
serializer.startTag(null, "body");
serializer.text(info.getBody());
serializer.endTag(null, "body");
serializer.startTag(null, "date");
serializer.text(info.getDate());
serializer.endTag(null, "date");
serializer.startTag(null, "address");
serializer.text(info.getAddress());
serializer.endTag(null, "address");
serializer.startTag(null, "type");
serializer.text(info.getType());
serializer.endTag(null, "type");
serializer.endTag(null, "sms");
}
serializer.endTag(null, "smss");
serializer.endDocument();
// 注意: flush
os.flush();
os.close();
}
5,Looper和Handler
http://blog.csdn.net/Innost/article/details/6055793
http://www.cnblogs.com/keyindex/articles/1822463.html
6 ,反编译的步骤
获取apk的资源文件
环境搭建:
apktool1.4.3.tar.bz2
apktool-install-windows-r04-brut1.tar.bz2
apktool-install-windows-r04-brut1.tar发现里面有两个文件,aapt.exe,apktool.bat 打开apktool.bat可以看到:
@echo off
java -jar "%~dp0\apktool.jar" %1 %2 %3 %4 %5 %6 %7 %8 %9
说该文件执行的是java命令,并且需要apktool.jar文件,所以把apktool1.4.3.tar.bz2解压,再把里面的apktool.jar文件复制到
aapt.exe,apktool.bat两个文件所在的目录
然后把要反编译的apk文件也复制到该目录,然后在cmd命令行进入该目录里输入:apktool d xxxx.apk
这样就得到了apk文件的资源文件了,当然我们也可以把apk文件按照解压的方式打开,如果资源文件被加密的话这种方式打开的资源文件是乱
码.最好还是使用命令的方式.
当然这个方式同样适用于反编译系统的资源,如android.jar里面的,如果我们只是单纯的解压,资源文件同样是乱码,最好还是使用命令的方式
.可以通过这种方式找到系统定义的权限和广播等
下载地址:http://code.google.com/p/android-apktool/downloads/list
获取apk文件中的class文件:
需要使用dex2jar 下载地址:http://code.google.com/p/dex2jar/downloads/list
先把dex2jar-0.0.9.7.zip解压,把apk文件里面的classes.dex文件复制到该目录下,然后使用命令:dex2jar classes.dex
然后使用jd-gui.exe查看生成的jar文件
jd-gui.exe下载地址:http://java.decompiler.free.fr/?q=jdgui
7,PopupWindow
弹出的窗体,
开销比 dialog大一些
activity的开销 小一些
//把popupWindow的布局转化成view对象
View popupView = inflater.inflate(R.layout.popup_item, null);
//从这个view对象中找到对应的控件
LinearLayout ll = (LinearLayout) popupView
.findViewById(R.id.ll_popup_item);
Animation animation = AnimationUtils.loadAnimation(
AppManagerActivity.this, R.anim.popup_enter);
ImageView iv_delete = (ImageView) popupView
.findViewById(R.id.iv_delete);
ImageView iv_start = (ImageView) popupView
.findViewById(R.id.iv_start);
ImageView iv_share = (ImageView) popupView
.findViewById(R.id.iv_share);
//为控件设置相应的点击事件
iv_delete.setOnClickListener(AppManagerActivity.this);
iv_delete.setTag(position);
iv_start.setOnClickListener(AppManagerActivity.this);
iv_start.setTag(position);
iv_share.setOnClickListener(AppManagerActivity.this);
iv_share.setTag(position);
//为popupWindow设置动画
ll.setAnimation(animation);
ll.startAnimation(animation);
//创建popupWindow对象
popupWindow = new PopupWindow(popupView,
LinearLayout.LayoutParams.WRAP_CONTENT,
view.getLayoutParams().height - 20);
// 非常重要 popupWindow一定要设置background
//如果不设置点击别处时,popupWindow不会消失.
Drawable background = getResources().getDrawable(
R.drawable.local_popup_bg);
popupWindow.setBackgroundDrawable(background);
// 获取到当前view(item)对象在窗体 上的location
int[] location = new int[2];
view.getLocationInWindow(location);
//显示popupWindow
//parent指的是popupWindow是被挂载到那一个控件上
popupWindow.showAtLocation(view, 51, location[0] + 60, location[1]);
8,判断是否是系统应用程序
/**
* 判断是否是系统应用程序
* @param info
* @return
*/
public boolean filterApp(ApplicationInfo info) {
if ((info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
return true;
} else if ((info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
return true;
}
return false;
}
9,根据包名和完整类名卸载,启动,分享程序
/**
* 删除指定包名的程序
* @param packname
*/
private void deleteApp(String packname) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_DELETE);
intent.setData(Uri.parse("package:" + packname));
// startActivity(intent);
startActivityForResult(intent, 0);
}
/**
* 根据包名开启某个应用程序
*
* @param packname
* @param activityname
*/
private void startApp(String packname, String activityname) {
if (activityname == null) {
Toast.makeText(this, "无法启动该应用", 1).show();
return;
}
// 1.获取传递进来包名对应apk的 具有luncher属性activity
Intent intent = new Intent();
Log.i(TAG, packname + "." + activityname);
intent.setClassName(packname, activityname);
startActivity(intent);
}
/**
* 分享程序
*
* @param appname
*/
private void shareApp(String appname) {
Intent intent = new Intent("android.intent.action.SEND");
intent.setType("text/plain");
intent.putExtra("android.intent.extra.SUBJECT", "f分享");
StringBuilder sb = new StringBuilder("Hi!推荐您使用软件:");
sb.append(appname);
intent.putExtra("android.intent.extra.TEXT", sb.toString());
intent = Intent.createChooser(intent, "分享");
startActivity(intent);
dismissPopupWindow();
}