mobile_numen_5
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(); }