Android 开发中一些很有用但你不知道的方法

来源:互联网 发布:linux tomcat自启动 编辑:程序博客网 时间:2024/05/16 06:10
  • setBackgroundResource(0) 可以移除 View 的背景色

  • Resources.getSystem().getDisplayMetrics().density 可以不用 Context 也能获取屏幕密度哦

  • 通过重载 ViewGroup 的 dispatchDraw 可以实现一个简单的蒙版效果。 例如下拉刷新时,可以在 contentView 上加一层遮罩。 canvas.drawRect(0, mContentView.getTranslationY(), getWidth(), getHeight(), mMaskPaint);

  • new 出来的 View 可以用 View.generateViewId() (API 17 以上可用) 生成 id,系统保证唯一

  • 使用 GridView时 android:padding 和android:clipToPadding="false" 配合使用效果更好哦。

  • 在布局文件中,如果只是为了占位,可以用 Space 来取代 View。 最棒的一点是Space可以跳过 Draw 这个过程。

  • TypedValue.applyDimension(int unit, float value, DisplayMetrics metrics) 方便dp, px, sp 之间的转换。

  • Activity.startActivities() 这个方法最直接的理解就是使用intent开启多个Activity

  • TextUtils.isEmpty() 如果传入的String 为NULL或者Length为0的话就返回 true。

  • Html.fromHtml() 如果你对Html熟悉的话,可以很迅速通过这个方法处理一些富文本操作。比如超链接和图文排版等处理。

  • TextView.setError() 设置文本框错误提醒

  • Build.VERSION_CODES 有些时候我们的app需要根据不同的SDK版本进行执行不同的操作

  • PhoneNumberUtils.convertKeypadLettersToDigits 这个方法简单粗暴,会将输入的字母根据键盘上的映射转换为数字。

  • ArgbEvaluator ArgbEvaluator.evaluate(float fraction, Object startValue, Object endValue);根据一个起始颜色值和一个结束颜色值以及一个偏移量生成一个新的颜色,分分钟实现类似于微信底部栏滑动颜色渐变。

  • ValueAnimator.reverse() 顺畅的取消动画效果

  • DateUtils.formatDateTime()) 这个方法可以输出相应格式化的时间或者日期

  • Pair 这个类 可以用来存储存储一”组”数据。但不是key和value的关系。

  • SparseArray 目前有很多地方从性能优化方说使用SparseArray来替换hashMap,来节省内存,提高性能。

  • Linkify.addLinks() 这个类可以更方便的为文本添加超链接。

  • android.media.ThumbnailUtils这个类主要是用来处理缩略图相关的工作,比如:用来获取媒体(图片、视频)的缩略图;

  • Bitmap.extractAlpha ();返回一个新的Bitmap,capture原始图片的alpha值。有的时候我们需要动态的修改一个元素的背景图片又不希望使用多张图片的时候,通过这个方法,结合Canvas和Paint可以动态的修改一个纯色Bitmap的颜色。

  • 模块间有消息需要传递时,使用LocalBroadcastManager替代Listener进行模块解耦。除了解耦,这样发送消息和执行消息差一个线程循环,可以减小方法的调用链,我这就碰到一次方法调用链太长导致StackOverflow的问题。

  • 静态变量不要直接或者间接引用Activity、Service等。这会使用Activity以及它所引用的所有对象无法释放,然后,用户操作时间一长,内存就会狂升。

  • Handler机制有一个特点是不会随着Activity、Service的生命周期结束而结束。也就是说,如果你Post了一个Delay的Runnable,然后在Runnable执行之前退出了Activity,Runnable到时间之后还是要执行的。如果Runnable里面包含更新View的操作,程序崩溃了。

  • 不少人在子线程中更新View时喜欢使用Context.runOnUiThread,这个方法有个缺点,就是一但Context生命周期结束,比如Activity已经销毁时,一调用就会崩溃。

  • SharedPreferences.Editor.commit这个方法是同步的,一直到把数据同步到Flash上面之后才会返回,由IO操作的不可控,尽量使用apply方法代替。apply只在API Level>=9才会支持,需要做兼容。不过,最新的 support v4 包已经为我们做好了处理,使用 SharedPreferencesCompat.EditorCompat.getInstance().apply(editor) 即可。

  • PackageManager.getInstalledPackages这个方法经常使用,你可能不知道,当获取的结果数量比较多的时候,在某些机型上面调用它花费的时间可能秒级的,所以尽量在子线程中使用。另外,如果结果太多,超过系统设置的Binder数据最大传输量的上限,则会发生TransactionException,如果你使用这个方法获取机器上的己安装应用列表,最好做一下预防。

  • 如果使用Context.startActivity启动外部应用,最好做一下异常预防,因为寻找不到对应的应用时,会抛出异常。如果你要打开的是应用内的Activity,不防使用显式Intent,这样能提高系统搜索目标Activity的效率。

  • Application的生命周期就是进程的生命周期。只有进程被干掉时,Application才会销毁。哪怕是没有Activity、Service在运行,Application也会存在。所以,为了减少内存压力,尽量不要在Application里面引用大对象、Context等。

  • getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);设置全屏方法一定要在setContentView之后

  • viewpager 的 setCurrentItem 一定要在 setAdapter 方法之后调用才会有效果.

  • 判断手机是不是飞行模式 boolean isEnabled = Settings.System.getInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 0) == 1;

  • 遍历HashMap的最佳方法

public static void printMap(Map mp) {   
 for (Map.Entry m : mp.entrySet()) {         System.out.println(m.getKey() + ":" + m.getValue());
   }}
  • 使用Java在一个区间内产生随机整数数

  • public static int randInt(int min, int max) { 
  •    Random rand = new Random();      int randomNum = rand.nextInt((max - min) + 1) + min;       return randomNum;}
  • 如果子类实现Serializable接口而父类未实现时,父类不会被序列化,但此时父类必须有个无参构造方法,否则会抛InvalidClassException异常。

  • transient关键字修饰变量可以限制序列化。

  • 当使用JakeWharton的TabPageIndicator时,如果需要先做一些耗时的操作,然后再展示TabPageIndicator的话,需要先设置mIndirector.setVisibility(View.GONE);然后耗时任务结束以后再mIndirector.setVisibility(View.VISIBLE);否则会报错

  • 类继承之间的调用顺序 父类static成员 -> 子类static成员 -> 父类普通成员初始化和初始化块 -> 父类构造方法 -> 子类普通成员初始化和初始化块 -> 子类构造方法

  • 华为手机无法显示log解决方案,.拨号界面输入(*#*#2846579#*#*) Service menu will appear.Go to "ProjectMenu" -> "Background Setting" -> "Log Setting"Open "Log switch" and set it to ON.Open "Log level setting" and set the log level you wish.

  • 后台service经常因为重启之类的出现onStartCommand()中的Intent传递的参数为null, 通过在onStartCommand()中的返回值改成return super.onStartCommand(intent, Service.START_REDELIVER_INTENT, startId); 可以解决问题。下面介绍几个flag的意思

    flag解释START_STICKY如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。START_NOT_STICKY“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务。START_REDELIVER_INTENT重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。START_STICKY_COMPATIBILITYSTART_STICKY的兼容版本,但不保证服务被kill后一定能重启。
  • 不能在Activity没有完全显示时显示PopupWindow和Dialog

  • 在多进程之间不要用SharedPreferences共享数据,虽然可以(MODE_MULTI_PROCESS),但极不稳定

  • 当Activity LauncherMode 为singleTask singleInstance时,使用startActivityForResult会立马返回,不能正常调用。具体请看http://www.360doc.com/content/15/0123/14/12928831_443085580.shtml

  • 当PopupWindow中有EditText控件时,因为Popupwindow 默认没有获取到焦点,需要手动设置焦点,这样子view才能获取到事件的监听。所以你需要在创建完popwindow后设置他的焦点,popupWindow.setFocusable(true);就可以让EditText获取焦点。

  • PopupWindow默认点击外部的时候不消失,需要对PopupWindow 设置一个背景图popWindow.setBackgroundDrawable(new BitmapDrawable());要创建一个空对象,设置为null是不行的,或者就创建一个全透明的背景图。

  • android中的序列化官方推荐Parceble,其实Parceble最好用于内存之间数据的交换,如果要把数据写入硬盘的话,推荐实现Serializable

  • tools标签可以很好的帮助开发者实时预览xml的效果,并且运行以后tools标签的内容不会展示出来.例如:

<TextView    android:layout_width="match_parent"    android:layout_height="wrap_content"    tools:text="这段话只在预览时能看到,运行以后就看不到了" />
  • android studio 2.1起已经支持jdk8了,使用的时候要在gradle中加上,需要把buildToolsVersion更新到24以上的版本

android {    defaultConfig {    ...            jackOptions {                enabled true            }        }   ...    compileOptions {        targetCompatibility 1.8        sourceCompatibility 1.8    }}
  • 6.0之后getResources().getColor()方法被废弃了,大家可以用ContextCompat.getColor(context, R.color.color_name)替换,ContextCompat 是 v4 包里的,请放心使用,另外还有getDrawable()等方法

  • 图片的资源文件官方推荐只把launcher放在mipmap文件夹下面,而app用到的资源文件建议放在drawable下面。

  • SharedPreference.Editor的apply是异步操作,不会返回成功的状态,而commit是同步操作,因此,在多个并发的提交commit的时候,他们会等待正在处理的commit保存到磁盘后再操作下一个数据,从而降低了效率。

  • 如果你在 manifest 中把一个 activity 设置成 android:windowSoftInputMode="adjustResize",那么 ScrollView(或者其它可伸缩的 ViewGroups)会缩小,从而为软键盘腾出空间。但是,如果你在 activity 的主题中设置了 android:windowFullscreen="true",那么 ScrollView 不会缩小。这是因为该属性强制 ScrollView 全屏显示。然而在主题中设置 android:fitsSystemWindows="false" 也会导致 adjustResize 不起作用

  • 在Android 4.0以后,在Manifest.xml中静态注册的广播,程序安装后必须启动一次才能接收到广播,比如你的应用监听开机启动的广播,必须要你的程序被运行过才能监听到

  • Activity的onDestory方法调用时机是不确定的(有时候离开界面很久之后才会调用onDestory方法),应该避免指望通过onDestory方法去释放与Activity相关的资源,否则会导致一些随机bug

  • 2.X时代Bitmap对象虽然存储在堆内存中,但是用了一个byte数组存储其像素信息。通过计数器来记录该像素信息被引用的个数。有人认为这个byte数组在native堆中,但事实上它也在堆中。只有在使用者调用recycle()后,Bitmap对象才会释放像素信息,才会在失去引用后被垃圾回收机制销毁。再加上DVM的heap size有严格的阀值,所以在使用大量图片资源的时候,及其容易发生OOM。解决办法一般都是,用一个哈希表存储Bitmap对象的软引用,作为内存缓存,并在适当时机掉用其recycle()。3.0以上版本Bitmap对象可以通过垃圾回收机制完全销毁,理论上不用再调用recycle()。

  • .gitignore只能忽略那些原来没有被track的文件,如果某些文件已经被纳入了版本管理中,则修改.gitignore是无效的。那么解决方法就是先把本地缓存删除(改变成未track状态),然后再提交:

git rm -r --cached .git add .git commit -m 'update .gitignore'
  • 时间戳请使用long或者String类型接收,遇到的坑,由于项目中的model好多都是通过GsonFormat生成的,服务器给的json中的时间戳都是10位的,导致了GsonFormat自动解析成了int, 当测试人员选择时间为2100年的时候时间戳是4开头的十位 用int类型接收越界了,导致报错

  • 为你的app添加默认布局样式,比如:每一个控件都需要写width和height属性,然而很多的控件的宽高属性都是wrap_content,那么我们可以通过在style文件添加如下样式:

<style name="Theme.YourApp" parent="android:style/Theme.Light">    <item name="android:layout_width">wrap_content</item>    <item name="android:layout_height">wrap_content</item></style>

这样,控件的宽高默认都是wrap_content样式啦。

  • 在style中写的样式通过视同parent标签来扩展你的样式,这样更高效,这里官方的建议是,只有Android自带的style才用parent标签,如果是自定义的style,直接用.符号来连接就行。如Fill.Height。

<style name="Fill">    <item name="android:layout_width">fill_parent</item>    <item name="android:layout_height">fill_parent</item></style><style name="Fill.Height" >    <item name="android:orientation">vertical</item></style>
  • Android上的应用切换按钮列出的其实不是应用而是Task,所以你会看到有的应用在切换视图里有多个任务。如果你的应用中有逻辑上相互独立的部分,或者想在多窗口环境下并排显示应用的两个不同部分,这种情况就适合多任务了。使用manifest属性(静态)或者 intent flags(动态)可以实现这一点,详见视频:http://v.youku.com/v_show/id_XMTU2ODk4NDg2NA==.html?f=26587294

  • 当app的theme用的是NoActionBar,但是在layout中仍然用到toolbar的时候,不要在style文件中加fitsSystemWindows属性,而是在用到toolbar的layout最外层加fitsSystemWindows,否则当你使用EditText,在小米手机上长按EditText调出系统粘贴功能的时候,粘贴的layout的布局会错位.

  • 当WebView与ScrollView嵌套使用,并且WebView有字体放大缩小的功能时,当切换webview的字体后,webview的高度并不能很好的计算出来,这时候可以通过注入的方式,让js算出高度,经测试,这样是最可靠的,代码地址:http://blog.csdn.net/jys1115/article/details/43525979

  • Context类中的createPackageContext(packageName, flags)方法,可用来获取指定包名应用程序的Context对象。

  • TextView类的setKeyListener(KeyListener)方法; 其中DigitsKeyListener类,使用getInstance(String accepted)方法即可指定EditText可输入字符集;

  • View类中的getLocationInWindow(int[])方法和getLocationOnScreen(int[])方法,获取View在窗口/屏幕中的位置;

  • Context.getCacheDir() - 可以获取到app默认的缓存路径。

  • StaticLayout 在自定义控件绘制文本的时候很有用。

  • Android中的四大组件千万不要通过new的方式创建出来。

  • 测试app的时候,我们大都想要将debug和release版本同时安装到手机里,可以通过在gradle中修改applicationid来实现:

android {    buildTypes {        debug {            applicationIdSuffix '.debug'            versionNameSuffix '-DEBUG'        }        release {            //...        }    }}
  • 在大多数的登陆界面中,都提供了用户是否让密码可见的选项,Support Library 24.2.0 提供了官方的实现,TextInputLayout 中添加了 passwordToggleEnabled 属性来开启此功能,并且可以通过 passwordToggleDrawable 设置图标。(摘自:Android笔记的微博)

  • 同样,在Support Library 24.2.0中增加RecyclerView 在快速滚动时的回调接口,SnapHelper是官方的一个实现OnFlingListener 的 一个抽象类,LinearSnapHelper 则是一个完整的实现.LinearSnapHelper默认实现的功能是类似ViewPager,在滚动结束后,会选择列表某一条居中展示(这里有开始位置展示,或者结束位置显示点我).例如:

    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false);    recyclerView.setLayoutManager(linearLayoutManager);    LinearSnapHelper snapHelper = new LinearSnapHelper();    snapHelper.attachToRecyclerView(recyclerView);
  • Android中推荐使用的数据结构 :

ArrayMap<K,V> in place of HashMap<K,V> ArraySet<K,V> in place of HashSet<K,V> SparseArray<V> in place of HashMap<Integer,V> SparseBooleanArray in place of HashMap<Integer,Boolean> SparseIntArray in place of HashMap<Integer,Integer>  SparseLongArray in place of HashMap<Integer,Long>  LongSparseArray<V> in place of HashMap<Long,V>
  • 生成GUID(由于java中只能生成UUID,所以这里要转换一下):

    return UUID.randomUUID().toString().toUpperCase().replaceAll("-", "");
  • 业务场景:需要定时后台扫描数据库,上传本地照片至云端,定时任务采用何种模式: 1.Handler或者Timer定时一般为秒级别的任务,Timer会启动额外线程,而Handler可以不用。 2.无论是Handler还是Timer都需要依赖于进程存活 3.利用Handler实现定时任务的类:HandlerTimer 4.如果时间较长,则需要使用AlarmManager 5.另外,我们对于这种业务应该优先考虑是否可以基于事件通知。 6.如果是加入媒体库的文件,我们可以使用registerContentObserver监听媒体库文件变化。

  • 把Activity作为参数传给一个静态方法,会影响这个Activity的正常销毁吗? 1.内存泄露与方法是否是静态与否无关,与内部的方法体实现有关系。 2.内存泄露可以简单理解成:生命周期长的对象不正确持有了持有了生命周期短的对象,导致生命周期短的对象无法回收。 3.比如Activity实例被Application对象持有,Activity实例被静态变量持有。






1 0
原创粉丝点击