当前位置:  编程技术>移动开发
本页文章导读:
    ▪newInstance() 跟 new 有什么区别        newInstance() 和 new 有什么区别? 在初始化一个类,生成一个实例的时候;newInstance() 和 new 有什么区别?   用newInstance与用new是区别的,区别在于创建对象的方式不一样,前者是使用类加.........
    ▪ (转)一种新的MAT使用方法分析内存溢出有关问题        (转)一种新的MAT使用方法分析内存溢出问题 相信很多人都用过MAT来分析内存溢出,而且网上有很多的使用方法,不过很多都是大同小异,而我今天介绍一种新的使用MAT的方法来快速定位问.........
    ▪ 说说APK反编译(代码安插)的那点事       说说APK反编译(代码插入)的那点事 很多人热衷于逆向工程,其过程中既可以学习作者的思路,又可以锻炼自己的能力,可谓是一举多得! 今天我来给大家伙介绍介绍我所了解的apk反编译的相关技术.........

[1]newInstance() 跟 new 有什么区别
    来源: 互联网  发布时间: 2014-02-18
newInstance() 和 new 有什么区别?
在初始化一个类,生成一个实例的时候;newInstance() 和 new 有什么区别?
  用newInstance与用new是区别的,区别在于创建对象的方式不一样,前者是使用类加载机制,那么为什么会有两种创建对象方式?这个就要从可伸缩、可扩展,可重用等软件思想上解释了。
  Java中工厂模式经常使用newInstance来创建对象,因此从为什么要使用工厂模式上也可以找到具体答案。
  例如:
  Class c = Class.forName(“A”);factory = (AInterface)c.newInstance();
  其中AInterface是A的接口,如果下面这样写,你可能会理解:
  String className = "A";Class c = Class.forName(className);factory = (AInterface)c.newInstance();
  进一步,如果下面写,你可能会理解:
  String className = readfromXMlConfig;//从xml 配置文件中获得字符串Class c = Class.forName(className);factory = (AInterface)c.newInstance();
  上面代码就消灭了A类名称,优点:无论A类怎么变化,上述代码不变,甚至可以更换A的兄弟类B , C , D....等,只要他们继承Ainterface就可以。
   从jvm的角度看,我们使用new的时候,这个要new的类可以没有加载;
  但是使用newInstance时候,就必须保证:1、这个类已经加载;2、这个类已经连接了。而完成上面两个步骤的正是class的静态方法forName()方法,这个静态方法调用了启动类加载器(就是加载java API的那个加载器)。
  有了上面jvm上的理解,那么我们可以这样说,newInstance实际上是把new这个方式分解为两步,即,首先调用class的加载方法加载某个类,然后实例化。
  这样分步的好处是显而易见的。我们可以在调用class的静态加载方法forName时获得更好的灵活性,提供给了我们降耦的手段。

[补充:]
newInstance: 弱类型。低效率。只能调用无参构造。
new: 强类型。相对高效。能调用任何public构造。
newInstance()是实现IOC、反射、面对接口编程 和 依赖倒置 等技术方法的必然选择,new 只能实现具体类的实例化,不适合于接口编程。
里面就是通过这个类的默认构造函数构建了一个对象,如果没有默认构造函数就抛出InstantiationException, 如果没有访问默认构造函数的权限就抛出IllegalAccessException

    
[2] (转)一种新的MAT使用方法分析内存溢出有关问题
    来源: 互联网  发布时间: 2014-02-18
(转)一种新的MAT使用方法分析内存溢出问题

相信很多人都用过MAT来分析内存溢出,而且网上有很多的使用方法,不过很多都是大同小异,而我今天介绍一种新的使用MAT的方法来快速定位问题原因,希望对大家有所帮助。

        本人最近一段时间都在忙android camera方面的项目,开发过程中遇到了一个很棘手的问题,就是不停的快速进相机和退出相机,这样重复大概十多次后程序就会崩溃,看log显示是out of memory,很明显是由于内存溢出导致的程序挂了,通过在网上搜集相关资料发现可以使用MAT工具来分析内存泄露问题,下面几个网站是我找到的关于内存溢出的文章,大家可以先借鉴下,在这也很感谢他们的分享:

       android 内存溢出问题分析

       http://blog.csdn.net/com360/article/details/6682409

       避免Android内存泄露

       http://blog.csdn.net/xyz_lmn/article/details/7108011

       android中context及全局变量小析

       http://blog.csdn.net/aomandeshangxiao/article/details/7008636

       Android内存分析工具

       http://blog.csdn.net/sunboy_2050/article/details/7031234

       Android 官方博客 - Android应用程序的内存分析(翻译)

       http://dev.10086.cn/blog/?uid-13136-action-viewspace-itemid-9580

       在我参与的camera项目中,看log表面上是显示由于内存不足导致图片导入不进去,可是我对于程序中的bitmap都进行过释放,感觉这个不是根本原因,而且试过将代码中的context换成Application context,可还是于事无补,最后通过MAT工具发现是由于代码中通过handler发送的大量消息在程序结束时没有清除掉,导致一系列引用不能被释放。所以在这里也补充一点,handler发送消息没有回收也可能会导致内存溢出。下面就让我介绍下如何使用MAT来分析问题吧(由于机密问题,所以没有把自己代码的截图呈上,请见谅)

       1.用MAT打开转换好的prohf文件,如下图1所示


                                                                                                                                                                      图1

        2.选择工具栏中的“Open Dominator Tree for entire heap”,如下图2所示


                                                                                                                                                              图2

        3.此时你会看到图中列出了一堆条目,而且很多都是你没见过或者不熟悉的,没关系,一般内存溢出都是由于我们自己写的代码导致的,所以先去找跟你包相关的条目,在这也说明下,往往这种操作很多次后才出现内存溢出的问题时,你会发现在图2中有很多相同的条目出现在一起,很可能问题就出在这里,所以先从这里下手,按照图2中的操作选择“exclude weak/soft references”,选择之后如下图3所示:


                                                                                                                                                                       图3

        4.同样在图3中,首先找跟你程序相关的条目然后一级一级的进入最终的跟路径,我们就能找到根本原因,是什么引用导致其他的一系列的资源不能被回收。在我的相机程序里最终发现是由于自己写的handler发送的消息在程序结束时一直没有清除,所以当我在程序中添加了mMainHandler.removeCallbacksAndMessages(null);问题就解决啦。。。


    
[3] 说说APK反编译(代码安插)的那点事
    来源: 互联网  发布时间: 2014-02-18
说说APK反编译(代码插入)的那点事

很多人热衷于逆向工程,其过程中既可以学习作者的思路,又可以锻炼自己的能力,可谓是一举多得! 今天我来给大家伙介绍介绍我所了解的apk反编译的相关技术,和大家一起来做一个逆向工程.

         提醒:未经授权而逆向别人的程序是违法行为! 在此,我们只做学术研究,不搞破坏~

 

知识铺垫:

1.反编译的结果有两种,一种是smali (java机器码),还有一种是大家喜闻乐见的java代码形式.

2.apk文件其实是一个zip压缩包,里面的目录结构与android工程的结构很类似,其中我们的java源码(包括R.java)在classes.dex文件中.

3.期间的工具大部分是java写的,运行时需要具备java环境!

我先介绍大家喜闻乐见的形式吧,哈哈…

 

将apk反编译为源码.

需要的工具:

1.dex2jar. dex2jar-0.0.7.10-SNAPSHOT.zip (590.31 KB, 下载次数: 44)

2011-7-8 20:25 上传
下载次数: 44

 

2.Jd-gui. jd-gui-0.3.3.osx.i686.zip (689.59 KB, 下载次数: 39)

2011-7-8 20:28 上传
下载次数: 39

 

3.AXMLPrinter2. AXMLPrinter2.zip (38.76 KB, 下载次数: 34)

2011-7-8 20:24 上传
下载次数: 34

 

 

逆向目标是前阵子悬赏区发过的一个demo,正好是我写的,我授权给所有cmd100用户,欢迎逆向,不追任何究法律责任..

源码:http://www.cmd100.com/bbs/forum- ... 052-pid-173308.html

Apk文件: CMD100.demo.slipButton.rar (18.74 KB, 下载次数: 19)

2011-7-8 20:32 上传
下载次数: 19

 

 

方法:

既然是一个zip压缩包,那就先把apk包解压出来吧!

可以看到解压出来的文件如下:

2011-7-8 20:29 上传
下载附件 (4.33 KB)

 

先处理xml 文件.. 你可能想直接打开xml文件,但其实xml文件被加密过了,打开只会是一堆你读不懂的东西,这需要用工具解码一下, 用到AXMLPrinter2.

打开CMD切换到AXMLPrinter2目录.

命令: Java –jar axmlprinter2.jar [路径]\AndroidManifest.xml >输出文件名.xml

2011-7-8 20:29 上传
下载附件 (14.7 KB)

 

打开生成的这个文件,看看Manifest.xml是不是出来了?

反编译结果:

  • <?xml version="1.0" encoding="utf-8"?>
  • <manifest
  • xmlns:android="http://schemas.android.com/apk/res/android"
  • android:versionCode="1"
  • android:versionName="1.0"
  • package="CMD100.demo.slipButton"
  • >
  • <application
  •   android:label="@7F040001"
  •   android:icon="@7F020000"
  •   android:debuggable="true"
  •   >
  •   <activity
  •    android:label="@7F040001"
  •    android:name=".Main"
  •    >
  •    <intent-filter
  •     >
  •     <action
  •      android:name="android.intent.action.MAIN"
  •      >
  •     </action>
  •     <category
  •      android:name="android.intent.category.LAUNCHER"
  •      >
  •     </category>
  •    </intent-filter>
  •   </activity>
  • </application>
  • <uses-sdk
  •   android:minSdkVersion="4"
  •   >
  • </uses-sdk>
  • </manifest>
  • 复制代码

    源文件:

  • <?xml version="1.0" encoding="utf-8"?>
  • <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  •       package="CMD100.demo.slipButton"
  •       android:versionCode="1"
  •       android:versionName="1.0">
  •     <application android:icon="@drawable/icon" android:label="@string/app_name">
  •         <activity android:name=".Main"
  •                   android:label="@string/app_name">
  •             <intent-filter>
  •                 <action android:name="android.intent.action.MAIN" />
  •                 <category android:name="android.intent.category.LAUNCHER" />
  •             </intent-filter>
  •         </activity>
  •     </application>
  •     <uses-sdk android:minSdkVersion="4" />
  • </manifest>
  • 复制代码

     

    使用同样的方法把res/layout/目录下的布局文件也解码一下~在此我就不再赘述了.

     

    接下来是dex文件的处理,需要用dex2jar工具处理转换一下.

    先把工具解压出来,然后CMD切换到指定目录,运行如下命令:

    dex2jar.bat [目录]\classes.dex

    2011-7-8 20:29 上传
    下载附件 (9.72 KB)

     

    执行完毕后,classes.dex所在目录下便生成了一个名为classes.dex.dex2jar.jar的文件!

    用jd-gui打开这个生成的jar试试!代码就在里面了有没有?!

    2011-7-8 20:29 上传
    下载附件 (20.64 KB)

     

    对比一下main.java吧.

    反编译:

  • public class Main extends Activity
  •   implements OnChangedListener
  • {
  •   public void OnChanged(boolean paramBoolean)
  •   {
  •     if (paramBoolean)
  •     {
  •       Toast.makeText(this, "打开了...", 0).show();
  •       return;
  •     }
  •     Toast.makeText(this, "关闭了...", 0).show();
  •   }
  •   public void onCreate(Bundle paramBundle)
  •   {
  •     super.onCreate(paramBundle);
  •     setContentView(2130903040);
  •     ((SlipButton)findViewById(2131034112)).SetOnChangedListener(this);
  •   }
  • }
  • 复制代码

    源文件:

  • public class Main extends Activity implements OnChangedListener {
  •     /** Called when the activity is first created. */
  •     @Override
  •     public void onCreate(Bundle savedInstanceState) {
  •         super.onCreate(savedInstanceState);
  •         setContentView(R.layout.main);
  •         
  •         SlipButton myBtn =(SlipButton) findViewById(R.id.slipBtn);//获得指定控件
  •         myBtn.SetOnChangedListener(this);//为控件设置监听器
  •     }
  • @Override
  • public void OnChanged(boolean CheckState) {//当按钮状态被改变时
  •   // TODO Auto-generated method stub
  •   if(CheckState)
  •    Toast.makeText(this,"打开了..." , Toast.LENGTH_SHORT).show();
  •   else
  •    Toast.makeText(this,"关闭了..." , Toast.LENGTH_SHORT).show();
  • }
  • }
  • 复制代码

     

     

     

    P.S.其实这样获得的源码还是有一部分会出现错误啊~

     

    =================分割线========================

     

    将apk反编译为smali并插入自己的代码

    用到的工具:

    1.apktool.jar (或smali-1.2.6.jar & baksmali-1.2.6.jar) Apktool.zip (2.01 MB, 下载次数: 27)

    2011-7-8 20:24 上传
    下载次数: 27

     

    2.auto-sign. APK-sign.rar (1.66 MB, 下载次数: 33)

    2011-7-8 20:22 上传
    下载次数: 33

     

     

    这些工具都是google的开源项目…

     

    主要流程:

    1.反编译

    2.插入代码

    3.重新打包

     

    方法:

    有了前面的铺垫,我就不再啰嗦了.

    命令:java -jar apktool.jar d 目标文件.apk

    2011-7-8 20:30 上传
    下载附件 (24.05 KB)

     

    在apktool.jar所在目录下就生成了这个apk反编译后的文件夹,打开看看!

    包括xml在内的文件都被解码了!

     

    不过我们关注的是smali文件夹,打开看看,里面的目录结构和源码的目录结构是一致的!

    找到要修改的地方.在这个例子里,就在Main.java(第一个载入的activity)的OnCreate方法里插入一段代码吧!

    打开 Main.smali

  • .class public LCMD100/demo/slipButton/Main;
  • .super Landroid/app/Activity;
  • .source "Main.java"
  • # interfaces
  • .implements LCMD100/demo/slipButton/OnChangedListener;

  • # direct methods
  • .method public constructor <init>()V
  •     .locals 0
  •     .prologue
  •     .line 14
  •     invoke-direct {p0}, Landroid/app/Activity;-><init>()V
  •     return-void
  • .end method

  • # virtual methods
  • .method public OnChanged(Z)V
  •     .locals 2
  •     .parameter "CheckState"
  •     .prologue
  •     const/4 v1, 0x0
  •     .line 28
  •     if-eqz p1, :cond_0
  •     .line 29
  •     const-string v0, "\u6253\u5f00\u4e86..."
  •     invoke-static {p0, v0, v1}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
  •     move-result-object v0
  •     invoke-virtual {v0}, Landroid/widget/Toast;->show()V
  •     .line 32
  •     :goto_0
  •     return-void
  •     .line 31
  •     :cond_0
  •     const-string v0, "\u5173\u95ed\u4e86..."
  •     invoke-static {p0, v0, v1}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
  •     move-result-object v0
  •     invoke-virtual {v0}, Landroid/widget/Toast;->show()V
  •     goto :goto_0
  • .end method
  • .method public onCreate(Landroid/os/Bundle;)V
  •     .locals 2
  •     .parameter "savedInstanceState"
  •     .prologue
  •     .line 18
  •     invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V
  •     .line 19
  •     const/high16 v1, 0x7f03
  •     invoke-virtual {p0, v1}, LCMD100/demo/slipButton/Main;->setContentView(I)V
  •     .line 21
  •     const/high16 v1, 0x7f05
  •     invoke-virtual {p0, v1}, LCMD100/demo/slipButton/Main;->findViewById(I)Landroid/view/View;
  •     move-result-object v0
  •     check-cast v0, LCMD100/demo/slipButton/SlipButton;
  •     .line 22
  •     .local v0, myBtn:LCMD100/demo/slipButton/SlipButton;
  •     invoke-virtual {v0, p0}, LCMD100/demo/slipButton/SlipButton;->SetOnChangedListener(LCMD100/demo/slipButton/OnChangedListener;)V
  •     .line 23
  •     return-void
  • .end method
  • 复制代码


    你发现里头的代码是见都没见过的格式,这就是java的汇编代码了…

    学过80x86汇编的同学看着这些代码是不是也觉得陌生?

    没事,我们可以对照前面介绍的那种方法查看源码,然后寻找修改的位置!

     

    找到这一行:

    .method public onCreate(Landroid/os/Bundle;)V

     

    这就是OnCreate方法的代码起始了,在

    .line 23

    return-void

     

    之前插入如下代码: (效果是Toast弹出一句话.)

  • const-string v0, "Hey,dude.This program has been fucked!"
  • const/4 v1, 0x0

  • invoke-static {p0, v0, v1}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;

  • move-result-object v0
  • invoke-virtual {v0}, Landroid/widget/Toast;->show()V
  • 复制代码

     

     

     

     

    为什么是这个,其实我也不懂smali,但是可以把自己要的功能写出来,再反汇编…然后copy到这来…

    好吧,我们来分析一下这段代码,前面是类似申明了两个变量,v0,v1,然后调用了Toast的makeText方法(列出了参数),再然后调用了其show方法…

    看吧,其实我们是能大概看懂smali的内容,只是不懂语法而已!

     

    好吧,废话不多说.

    现在改好了,用apktool重新打包~

    命令: java -jar apktool.jar b 目标文件夹

    2011-7-8 20:30 上传
    下载附件 (7.77 KB)

     

    执行完后,就在这个目录里生成了两个目录,分别是build,dist

    Build下是中间文件,dist下则是apk文件(但是这个apk文件未签名)

     

    下面就是重新签名了.

    先解压auto-sign

    我们进入Build文件夹,复制apk文件夹到auto-sign文件夹下,然后执行命令:

    sign_pack.bat apk

     

    稍等片刻,你会发现文件夹下生成了对应的目录,进入这个目录,apk静静地躺在那…

    赶紧,装到手机上看看,是不是改成了?

    2011-7-8 20:41 上传
    下载附件 (7.76 KB)

     

    成功弹出,哈哈...

     

    至此,apk的反编译和代码插入就结束了.

    借此方法,我们可以轻松的对apk进行DIY...

     

    欢迎转载,但,转载请注明出处!


        
    最新技术文章:
    ▪Android开发之登录验证实例教程
    ▪Android开发之注册登录方法示例
    ▪Android获取手机SIM卡运营商信息的方法
    ▪Android实现将已发送的短信写入短信数据库的...
    ▪Android发送短信功能代码
    ▪Android根据电话号码获得联系人头像实例代码
    ▪Android中GPS定位的用法实例
    ▪Android实现退出时关闭所有Activity的方法
    ▪Android实现文件的分割和组装
    ▪Android录音应用实例教程
    ▪Android双击返回键退出程序的实现方法
    ▪Android实现侦听电池状态显示、电量及充电动...
    ▪Android获取当前已连接的wifi信号强度的方法
    ▪Android实现动态显示或隐藏密码输入框的内容
    ▪根据USER-AGENT判断手机类型并跳转到相应的app...
    ▪Android Touch事件分发过程详解
    ▪Android中实现为TextView添加多个可点击的文本
    ▪Android程序设计之AIDL实例详解
    ▪Android显式启动与隐式启动Activity的区别介绍
    ▪Android按钮单击事件的四种常用写法总结
    ▪Android消息处理机制Looper和Handler详解
    ▪Android实现Back功能代码片段总结
    ▪Android实用的代码片段 常用代码总结
    ▪Android实现弹出键盘的方法
    ▪Android中通过view方式获取当前Activity的屏幕截...
    ▪Android提高之自定义Menu(TabMenu)实现方法
    ▪Android提高之多方向抽屉实现方法
    ▪Android提高之MediaPlayer播放网络音频的实现方法...
    ▪Android提高之MediaPlayer播放网络视频的实现方法...
    ▪Android提高之手游转电视游戏的模拟操控
     


    站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3