2016-06-23 00:05:54 quotHeiMing39 阅读数 119
  • Android Studio 开发详解

    Android Studio教程,该教材会详细介绍Android Studio如何使用,包括在Windows平台下载安装Android Studio、配置、代码重构、项目调试、jar包管理等。

    10819 人正在学习 去看看 郭宏志

android代码整理

  • 在需要跳转的activity内,定义intent
    /*在需要跳转的activity内,对intent属性进行定义。这样在第一个activity内,仅需要定义需求的参数*/
   public static Intent getStartIntent(Context context, @NonNull String paramOne, @Nullable String paramTwo) {
        Intent intent = new Intent(context, XXXXActivity.class);
        intent.putExtra(EXTRA_PARAM_ONE, paramOne);
        if (paramTwo != null) {
            intent.putExtra(EXTRA_PARAM_TWO, paramTwo);
        }
        return intent;
    }

  • 用/**/代替//来进行注释

推荐注释:

  /*提交成功布局*/
    private LinearLayout commitSuccessLayout;

不推荐注释:

    private LinearLayout commitSuccessLayout;//提交成功布局

  • 为每一个需要监听的view,量身定做listener,使逻辑更清晰
    推荐方法:
    private View.OnClickListener commitButtonClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //TODO
        }
    };
    private View.OnClickListener deleteButtonClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //TODO
        }
    };
commitButton.setOnClickListener(commitButtonClickListener);            deleteButton.setOnClickListener(deleteButtonClickListener);

不推荐方法:

          commitButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //TODO
                }
            });
            deleteButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //TODO
                }
            });
        }
    };

  • 在使用局部变量的之前,再定义它
    推荐方法:
  String uid = String.valueOf(mLoginAccountEdit.getText());
   if (TextUtils.isEmpty(uid)) {
          showToast("手机号码不能为空!", Toast.LENGTH_SHORT);
                return false;
        }
 *
 *
 *
 *
 *
String pwd = String.valueOf(mLoginPwdEdit.getText());
 if (TextUtils.isEmpty(pwd)) {
      showToast("密码不能为空!", Toast.LENGTH_SHORT);
                  return false;
        }
 *
 *
 *
 *
 *

不推荐方法:

 String uid = String.valueOf(mLoginAccountEdit.getText());
 String pwd = String.valueOf(mLoginPwdEdit.getText());
 *
 *
 *
 *
 *
 if (TextUtils.isEmpty(pwd)) {
      showToast("密码不能为空!", Toast.LENGTH_SHORT);
                  return false;
        }
   if (TextUtils.isEmpty(uid)) {
          showToast("手机号码不能为空!", Toast.LENGTH_SHORT);
                return false;
        }
  • 将复杂的步骤,拆分成多个小步骤

推荐的方法

public interface IFirstStep {
    public String openTheDoor();
}
public interface ISecondStep {
     String sendTheElephantIntoTheFridge();
}
public interface IThirdStep {
    String closeTheDoor();
}
public class FirstStep implements IFirstStep {
    @Override
    public String openTheDoor() {
        return "open the door";
    }
}
public class SecondStep implements ISecondStep{
    @Override
    public String sendTheElephantIntoTheFridge() {
        return "send the elephant into the fridge";
    }
}
public class ThirdStep implements IThirdStep {
    @Override
    public String closeTheDoor() {
        return "close the door";
    }
}
public class CloseTheElephant {
    private IFirstStep iFirstStep;
    private ISecondStep iSecondStep;
    private IThirdStep iThirdStep;

    public CloseTheElephant(IFirstStep iFirstStep, ISecondStep iSecondStep, IThirdStep iThirdStep) {
        this.iFirstStep = iFirstStep;
        this.iSecondStep = iSecondStep;
        this.iThirdStep = iThirdStep;

    }

    public String Work() {
        String stepOne = iFirstStep.openTheDoor();
        String stepTwo = iSecondStep.sendTheElephantIntoTheFridge();
        String stepThree = iThirdStep.closeTheDoor();
        return stepOne + stepTwo + stepThree;
    }
  CloseTheElephant closeTheElephant = new CloseTheElephant(new FirstStep(), new SecondStep(), new ThirdStep());
        Log.i("Dingo", closeTheElephant.Work());

把每一小步,拆分出来。逻辑更加清晰,日后维护更加方便

2017-09-06 09:10:14 binjianliu 阅读数 217
  • Android Studio 开发详解

    Android Studio教程,该教材会详细介绍Android Studio如何使用,包括在Windows平台下载安装Android Studio、配置、代码重构、项目调试、jar包管理等。

    10819 人正在学习 去看看 郭宏志

Android Studio代码混淆

一、app下的build.gradle文件中添加如下代码

buildTypes {
    release {
        minifyEnabled true //是否混淆  true:混淆  false:不混淆   默认false
        
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    
}
}

//proguard-android.txt 文件是本地sdk/tools/proguard文件夹下的默许文件

//proguard-rules.pro文件就是用来编写混淆代码的

二、接下来就是在prguard-rules.pro文件中编写混淆代码

1. 代码混淆详解(参数详解)

# 指定代码的压缩级别
-optimizationpasses 5  
# 是否使用大小写混合    
-dontusemixedcaseclassnames
# 是否混淆第三方jar                                                   
-dontskipnonpubliclibraryclasses     
# 混淆时是否做预校验                                              
-dontpreverify     
# 混淆时是否记录日志                                                             
-verbose      
# 混淆时所采用的算法(优化)
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

# 1句是导入第三方的类库,防止混淆时候读取包内容出错
-libraryjars libs/youjar.jar

         
      
# 保持哪些类不被混淆
-keep public class * extends android.app.Activity                                
-keep public class * extends android.app.Application  

-keep public class * extends android.app.Fragment                          
-keep public class * extends android.app.Service                                  
-keep public class * extends android.content.BroadcastReceiver                    
-keep public class * extends android.content.ContentProvider                      
-keep public class * extends android.app.backup.BackupAgentHelper                 
-keep public class * extends android.preference.Preference                        
-keep public class com.android.vending.licensing.ILicensingService                
      
# 保持 native 方法不被混淆
-keepclasseswithmembernames class * {                                            
    native <methods>;  
}  

# 保持自定义控件类不被混淆      
-keepclasseswithmembers class * {                                                 
    public <init>(android.content.Context, android.util.AttributeSet);  
}  
  
# 保持自定义控件类不被混淆  
-keepclasseswithmembers class * {  
    public <init>(android.content.Context, android.util.AttributeSet, int);       
}  

# 保持自定义控件类不被混淆      
-keepclassmembers class * extends android.app.Activity {                          
    public void *(android.view.View);  
}  

# 保持枚举 enum 类不被混淆      
-keepclassmembers enum * {                                                        
    public static **[] values();  
    public static ** valueOf(java.lang.String);  
}  

# 保持 Parcelable 不被混淆      
-keep class * implements android.os.Parcelable {                                  
    public static final android.os.Parcelable$Creator *;  
}  

# 保持自己定义的类不被混淆      
-keep class MyClass;

 

2. 代码混淆举例一

#-----------------混淆配置设定--------------------------------------
#指定代码压缩级别
-optimizationpasses 5
#混淆时不会产生形形色色的类名                                                      
-dontusemixedcaseclassnames
#指定不忽略非公共类库                                                 
-dontskipnonpubliclibraryclasses
#不预校验,如果需要预校验,是-dontoptimize                                            
-dontpreverify
#屏蔽警告                                                              
-ignorewarnings
#混淆时记录日志                                                             
-verbose
#优化                                                                    
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*    

#----导入第三方包,但是在当前版本中使用会报 input jar file is specified twice 错误,所以注释掉
#-libraryjars libs/android.support.v4.jar
#-libraryjars libs/BaiduLBS_Android.jar
#-libraryjars libs/commons-httpclient-3.1.jar
#-libraryjars libs/jackson-annotations-2.1.4.jar
#-libraryjars libs/jackson-core-2.1.4.jar
#-libraryjars libs/jackson-databind-2.1.4.jar
#-libraryjars libs/xUtils-2.6.14.jar
#-----------------不需要混淆第三方类库------------------------------------------------------------------
#去掉警告
-dontwarn android.support.v4.**                                             
#过滤android.support.v4
-keep class android.support.v4.** { *; }                                    
-keep interface android.support.v4.app.** { *; }
-keep public class * extends android.support.v4.**
-keep public class * extends android.app.Fragment

#过滤commons-httpclient-3.1.jar
-keep class org.apache.**{*;}                                               

#过滤jackson-core-2.1.4.jar
-keep class com.fasterxml.jackson.**{*;}                                    

#去掉警告
-dontwarn com.lidroid.xutils.**                                             
#过滤xUtils-2.6.14.jar
-keep class com.lidroid.xutils.**{*;}                                       
#这是xUtils文档中提到的过滤掉注解
-keep class * extends java.lang.annotation.Annotation{*;}                   

#去掉警告
-dontwarn com.baidu.**                                                      
-dontwarn com.baidu.mapapi.**
#过滤BaiduLBS_Android.jar
-keep class com.baidu.** {*;}                                               
-keep class vi.com.gdi.bgl.android.**{*;}
-keep class com.baidu.platform.**{*;}
-keep class com.baidu.location.**{*;}
-keep class com.baidu.vi.**{*;}

#-----------------不需要混淆系统组件等-------------------------------------------------------------------
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService

#过滤掉自己编写的实体类
-keep class com.classtc.test.entity.**{*;}                                   


#------保护指定的类和类的成员,但条件是所有指定的类和类成员是要存在-----------
-keepclasseswithmembernames class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembernames class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

 

 

3. 代码混淆举例二

#指定代码的压缩级别
-optimizationpasses 5

#包明不混合大小写
-dontusemixedcaseclassnames

#不去忽略非公共的库类
-dontskipnonpubliclibraryclasses

 
#优化  不优化输入的类文件
-dontoptimize

#不混淆输入的类文件
-dontobfuscate

 
#预校验
-dontpreverify

 
# 有了verbose这句话,混淆后就会生成映射文件
 # 包含有类名->混淆后类名的映射关系
 # 然后使用printmapping指定映射文件的名称
 
-verbose
 -printmapping
priguardMapping.txt

 # 混淆时所采用的算法
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

#保护注解
-keepattributes *Annotation*

# 抛出异常时保留代码行号
-keepattributes SourceFile,LineNumberTable

# 保持哪些类不被混淆
-keep public class * extends android.app.Fragment
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
#如果有引用v4包可以添加下面这行
-keep public class * extends android.support.v4.app.Fragment

#如果引用了v4或者v7
-dontwarn android.support.**

# 保留Activity中的方法参数是view的方法,
    # 从而我们在layout里面编写onClick就不会影响
    
-keepclassmembers class * extends android.app.Activity {
        public void * (android.view.View);
    
}

    -keep public class * extends android.view.View {
            public <init>(android.content.Context);
            public <init>(android.content.Context, android.util.AttributeSet);
            public <init>(android.content.Context, android.util.AttributeSet, int);
            public void set*(...);
            *** get* ();
        
}

        #保持 native 方法不被混淆
    
-keepclasseswithmembernames class * {
            native <methods>;
        
}

        #保持自定义控件类不被混淆
    
-keepclasseswithmembers class * {
            public <init>(android.content.Context, android.util.AttributeSet);
        
}
    #保持 Parcelable 不被混淆
    
-keep class * implements android.os.Parcelable {
      public static final android.os.Parcelable$Creator *;
    
}

    #保持 Serializable 不被混淆
    
-keep public class * implements java.io.Serializable {
        public *;
    
}

    -keepclassmembers class * implements java.io.Serializable {
        static final long serialVersionUID;
        private static final java.io.ObjectStreamField[] serialPersistentFields;
        !static !transient <fields>;
        !private <fields>;
        !private <methods>;
        private void writeObject(java.io.ObjectOutputStream);
        private void readObject(java.io.ObjectInputStream);
        java.lang.Object writeReplace();
        java.lang.Object readResolve();
    
}

    #不混淆资源类
    
-keepclassmembers class **.R$* {
        public static <fields>;
    
}

    # 对于带有回调函数onXXEvent的,不能混淆
    
-keepclassmembers class * {
        void *(**On*Event);
    
}

#移除log 测试了下没有用还是建议自己定义一个开关控制是否输出日志
-assumenosideeffects class android.util.Log {
    public static boolean isLoggable(java.lang.String, int);
    public static int v(...);
    public static int i(...);
    public static int w(...);
    public static int d(...);
    public static int e(...);
}

-dontwarn com.squareup.**
-keep class com.squareup.**{*; }

-dontwarn org.apache.**
-keep class org.apache.**{*;}

-dontwarn com.tencent.**
-keep class com.tencent.**{*;}

-dontwarn com.sina.**
-keep class com.sina.**{*;}

-dontwarn com.baidu.**
-keep class com.baidu.**{*;}

-dontwarn com.alipay.**
-keep class com.alipay.**{*;}

-dontwarn org.json.alipay.**
-keep class org.json.alipay.**{*;}

-dontwarn org.apache.http.entity.mime.**
-keep class org.apache.http.entity.mime.**{*;}

-dontwarn com.rongkecloud.**
-keep class com.rongkecloud.**{*;}

-dontwarn com.rongke.**
-keep class com.rongke.**{*;}

-dontwarn org.**
-keep class org.**{*;}

-dontwarn a.a.a.a.a.**
-keep class a.a.a.a.a.**{*;}

-dontwarn chat.demo.entity.**
-keep class chat.demo.entity.**{*;}

-dontwarn av.demo.entity.**
-keep class av.demo.entity.**{*;}

 -dontwarn com.google.zxing.**
 -keep class com.google.zxing.**{*;}

-dontwarn com.lking.demo.entity.**
-keep class com.lking.demo.entity.**{*;}

-keep class com.youth.banner.** {
    *;
 
}

-keepattributes *JavascriptInterface*
-keepclassmembers class com.lking.demo.ui.find.JstoAndroid$JsInterface {
  public *;
}


-keepattributes *JavascriptInterface*
-keepclassmembers class com.lking.androidlib.widget.WebView$*{
    *;
}

#facebook fresco
-keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip

# Do not strip any method/class that is annotated with @DoNotStrip
-keep @com.facebook.common.internal.DoNotStrip class *
-keepclassmembers class * {
    @com.facebook.common.internal.DoNotStrip *;
}
# Keep native methods
-keepclassmembers class * {
    native <methods>;
}
-dontwarn okio.**
-dontwarn javax.annotation.**
-dontwarn com.android.volley.toolbox.**

 

 

2016-01-20 14:53:42 industriously 阅读数 8883
  • Android Studio 开发详解

    Android Studio教程,该教材会详细介绍Android Studio如何使用,包括在Windows平台下载安装Android Studio、配置、代码重构、项目调试、jar包管理等。

    10819 人正在学习 去看看 郭宏志

阅读源码很枯燥,如果能单步调试岂不是能使逻辑更清晰,本文章讲如何调适android framework。本文使用的环境是ubuntu 14.04,jdk1.6。Android4.4.2源码(有兴趣可以去下载更新版本的代码,其他版本源码编译需要的jdk版本不同,请配置合适的jdk),Android Studio调试其他版本源码framework同理。

如已经编译过源码请跳过1,2步骤。

1.下载android源代码

官网下载https://source.android.com/source/downloading.html(需要翻墙,安装git,repo)。
国内网盘下载http://blog.csdn.net/ilittleone/article/details/6823441

2.编译android源码

官网https://source.android.com/source/building.html
步骤:
a.初始化环境,在源码目录中执行
source build/envsetup.sh或者. build/envsetup.sh
b.选择build类型
lunch aosp_arm-eng
有三种类型:user,userdebug ,eng
这里选择eng
c.开始编译
make -j4
j后边的数字是使用几个线程编译,根据自己cpu配置自行决定,一半为核心数目2倍。
然后就是漫长等待,中间出现各种错误,自行网上搜索解决,大多都是缺少各种配置环境,挨个安装就好。

3.生成android.ipr和android.iml文件

进入Android 源码根目录
执行
mmm development/tools/idegen/
这行命令的意思是编译idegen这个项目,生成idegen.jar文件.生成成功后,会显示这个jar包的位置,并显示 #### make completed successfully
然后执行
sh ./development/tools/idegen/idegen.sh
这行命令的意思是生成对应的文件:android.iws, android.ipr, android.iml .

这里写图片描述

4.android studio导入源码

生成上述对应的文件后,打开Android Studio,选择打开一个现有的Android Studio项目,选择Android源码的根目录,导入即可(起作用的是android.irp文件).在配置sdk版本之后就可以查看Android 源码了.
导入过程比较慢,可以打开android.iml参考网上文章过滤掉一些模块。

这里写图片描述

5.调试代码

Run->Attach debugger to Android process选择要调试的程序

这里写图片描述

选择要调试的程序。

这里写图片描述

这里选择了自己的一个程序,来调试ListView,虚拟机中国年滑动下ListView,编辑器中进入了断点,这样就可以开开心心的,一步一步研究android的一些源码的原理

这里写图片描述

注意:
调试的时候,国产手机有的断点进不去,可能是厂商修改了framework的原因(具体有待考证)所以我这里使用的是虚拟机。

参考:

Android官网http://source.android.com
http://www.jianshu.com/p/c85984cf99e2

2016-05-30 21:43:27 caoxiao90 阅读数 1908
  • Android Studio 开发详解

    Android Studio教程,该教材会详细介绍Android Studio如何使用,包括在Windows平台下载安装Android Studio、配置、代码重构、项目调试、jar包管理等。

    10819 人正在学习 去看看 郭宏志

Android Lint

Android Lint是安卓强烈推荐的代码扫描工具,我会对官方的文档做一些翻译,并结合自己的理解进行一些整理。你也可以直接访问官方文档查看文档。 原文链接: https://developer.android.com/studio/write/lint.html?hl=zh-cn

在保证你的应用功能需求测试通过的同时,保证你的代码没有结构性错误也非常的重要。结构糟糕的代码,将会对你的应用可靠性和效率带来不利的影响,也会让代码难以维护。比如,你的xml中有未被使用的命名空间,既占用了空间,也会招致多余的处理。其他的错误,例如使用过时的api或者目标版本不支持的api,也会让代码运行不正确。

概述

Android Studio提供了一个叫做Lint的代码扫描工具,能够帮助你轻松地找出并修复代码中的质量问题,不需要运行应用和写测试用例。工具把每个问题按照问题描述和严重级别报告给你,你也可以配置错误的严重等级忽略与项目不相关的错误,也可以提升错误的等级。这个工具有命令行结果,你可以很方便的集成进来做自动测试。
下面是Lint工具的工作原理。

这里写图片描述

Lint扫描流程
Application source files
应用资源文件包括代码,xml文件,图标文件,混淆器配置文件。

lint.xml文件
用来配置你想排除或者自定义的问题严重等级。

Lint工具
这个就是静态代码扫描的工具。

扫描结果
可以在控制台或者事件日志等地方看到扫描结果。

在Android Studio中运行

在Android Studio中,当你编译程序的时候,Lint会自动运行。查看修改问题严重等级,你可以打开设置File > Settings > Editor > Inspections 进行修改,这个是windows的设置,mac基本大同小异。在build.gradle中也可以修改配置。

android {
    lintOptions {
       // 设置成true关闭lint的分析进程
       quiet true
       // 设置成true, 当发现问题的时候就会终止gradle build
       abortOnError false
       // 设置成true,只报告错误
       ignoreWarnings true
       }
       ...
    }

也可以手动执行扫描,在Analyze > Inspect Code下,然后制定扫描的范围。

在命令行执行lint

lint [flags] <project directory>

举个例子,你可以用下面的命令去扫描myproject工程目录以及子目录。错误的ID是MissingPrefix,只扫描xml文件没有命名空间前缀的错误。

lint --check MissingPrefix myproject

其他的命令和参数可以通过下面这个方法查看:

lint --help

lint输出示例

下面是Lint扫描Earthquake项目后的结果:

$ lint Earthquake

Scanning Earthquake: ...............................................................................................................................
Scanning Earthquake (Phase 2): .......
AndroidManifest.xml:23: Warning: <uses-sdk> tag appears after <application> tag [ManifestOrder]
  <uses-sdk android:minSdkVersion="7" />
  ^
AndroidManifest.xml:23: Warning: <uses-sdk> tag should specify a target API level (the highest verified version; when running on later versions, compatibility behaviors may be enabled) with android:targetSdkVersion="?" [UsesMinSdkAttributes]
  <uses-sdk android:minSdkVersion="7" />
  ^
res/layout/preferences.xml: Warning: The resource R.layout.preferences appears to be unused [UnusedResources]
res: Warning: Missing density variation folders in res: drawable-xhdpi [IconMissingDensityFolder]
0 errors, 4 warnings

输入了4个警告,0个错误。错误的原因和位置都已经展示出来了,所以很方便找到并修复他们。

在代码和xml中配置lint

如果要忽略部分检查可以这样做:

@SuppressLint("NewApi")
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
@SuppressLint("ParserError")
public class FeedProvider extends ContentProvider {

xml中是这样的

namespace xmlns:tools="http://schemas.android.com/tools"
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:ignore="UnusedResources" >

    <TextView
        android:text="@string/auto_update_prompt" />
</LinearLayout>
tools:ignore="NewApi,StringFormatInvalid"

Infer

Infer 是facebook推出的一款静态代码扫描工具,支持Objective-C, Java, 和 C。使用过后觉得还不错,推荐给大家。
我是通过brew安装的,命令如下:

brew install infer

运行检查也非常简单

infer -- gradle xxxx(最后代表你要检查的项目名)

扫描的时间看项目大小,如果项目很大会特别的久,需要耐心等待。

扫描结果:
这里写图片描述

这里写图片描述

统计了不同的错误类型,还有错误代码的位置很详细,可能方便很多快找到问题。主要三种错误,可能的空指针,资源没释放:例如数据库或者输入输出流没有释放,context泄露。

有了这些工具帮助我们,我们项目中crash率和性能都得到了大大的提升,用户体验提升了不止一点点。

Android 混淆代码总结

阅读数 172968

Android 混淆代码总结

博文 来自: lovexjyong

Android代码混淆

阅读数 921

没有更多推荐了,返回首页