列表
SoftReference和WeakReference
当try{}中有return时,finally{}中的代码还会不会被执行?
sendMessage和sendToTarget,一个是Handler类的方法, 一个是Message类的方法
Android 更新UI的两种方法——handler和runOnUiThread(runnable)
为什么在方法内创建匿名内部类的对象时, 方法中的局部变量要声明为final的
反射的应用场景
transient关键字
@SuppressWarings注解的作用
什么时候用接口, 什么时候用抽象类.
什么是抽象类和匿名内部类,以及为什么要使用它们
volatile关键字修饰的变量, 对其操作为原子级.
定义static内部类就相当于直接写了一个.java的文件
StringBuffer和StringBuilder的区别
JSONObject optString与getString的区别

=========================================

SoftReference和WeakReference

强引用: 直接的对象引用
软引用 SoftReference : 当一个对象只有软引用存在时,系统内存不足时此对象会被gc回收.

String str=new String("abc");SoftReference softRef=new SoftReference(str);String str2 = softRef.get();if(str2 != null) {  //直接使用} else {  //已经被gc回收}

弱引用 WeakReference : 当一个对象只有弱引用存在时,此对象会随时被gc回收.
弱引用是最弱的.

String str=new String("abc");WeakReference weakRef=new WeakReference(str);String str2 = weakRef.get();if(str2 != null) {  //直接使用} else {  //已经被gc回收}
当try{}中有return时,finally{}中的代码还会不会被执行?

yes

public static void main() {        int a = f_test();        Log.i("ahking","333, a = " +a);}public static int f_test() {    int a = 0;    try {        a = 1;        Log.i("ahking","111");        return a;    } finally {        Log.i("ahking","222");        a = 2;        return a;    }}

logcat:

10-22 08:02:33.871  19565-19565/com.qihoo.browser I/ahking﹕ 11110-22 08:02:33.871  19565-19565/com.qihoo.browser I/ahking﹕ 22210-22 08:02:33.871  19565-19565/com.qihoo.browser I/ahking﹕ 333, a = 2

结论:
try{}中有return; finally{}也会被执行.
finally{}中如果有return;將覆盖try{}中的return,作为函数的出口. 但不是一个好的编程习惯, 这点了解一下即可, 实际开发中不要这么用.

sendMessage和sendToTarget,一个是Handler类的方法, 一个是Message类的方法
Message message = mHandler.obtainMessage();message.what = MSG_QUERY_MOBILE_BOOKMARK;message.obj = infos;message.sendToTarget();//实际上调用的就是创建message时用的handler对象.

就相当于:

Message msg = Message.obtain(null, MSG_HANDLE_LOCATION_FAILED, 0, 0);mHandler.sendMessage(msg);

源码:

Handler.javapublic final Message obtainMessage(){    return Message.obtain(this);}public static Message obtain(Handler h) {    Message m = obtain();    m.target = h;    return m;}
Message.javaHandler target; public void sendToTarget() {    target.sendMessage(this);}
Android 更新UI的两种方法——handler和runOnUiThread(runnable)

通过handler执行更新UI的任务,是最常用的方法, 这里就不多说了, 除了这个方法, android还为Activity类提供了一个runOnUiThread(runnable)方法, 也可以用来执行更新UI的任务.

创建Activity对象时, 会在它内部创建一个Handler对象, 目的就是不管在UI线程还是非UI线程中, 都能够通过Activity的对象调用runOnUiThread(runnable)去执行一个更新UI的任务. 如果runOnUiThread(runnable)执行在UI线程,那么这个runnable对象立即执行,如果执行在非UI线程, 那么这个runnable对象就被mHandler封装成msg,压入它所关联的消息队列MessageQueue, 等待UI线程空闲时,被UI线程执行.

Activity.java源码:public class Activity {    final Handler mHandler = new Handler();    ...    public final void runOnUiThread(Runnable action) {        if (Thread.currentThread() != mUiThread) {            mHandler.post(action);        } else {            action.run();        }    }    ...}
为什么在方法内创建匿名内部类的对象时, 方法中的局部变量要声明为final的

内部类通常都含有回调,引用那个匿名内部类的函数执行完了就没了,所以内部类中引用外面的局部变量需要是final的,这样在回调的时候才能找到那个变量,而如果是外围类的成员变量就不需要是final的,因为内部类本身都会含有一个外围了的引用(外围类.this),所以回调的时候一定可以访问到。例如下面:

private Animator createAnimatorView(final View view, final int position) {    MyAnimator animator = new MyAnimator();    animator.addListener(new AnimatorListener() {        @Override        public void onAnimationEnd(Animator arg0) {            Log.d(TAG, "position=" + position);         }    });    return animator;}

内部类回调里访问position的时候createAnimatorView()早就执行完了,position如果不是final的,回调的时候肯定就无法拿到它的值了,因为局部变量在函数执行完了以后就被回收了。
refer:
http://www.zhihu.com/question/21395848

反射的应用场景
使用被隐藏的类和方法.
package com.android.internal.policy;import android.content.Context;import android.view.FallbackEventHandler;import android.view.LayoutInflater;import android.view.Window;import android.view.WindowManagerPolicy;/** * {@hide} */public final class PolicyManager {    private static final String POLICY_IMPL_CLASS_NAME =        "com.android.internal.policy.impl.Policy";    private static final IPolicy sPolicy;    static {        // Pull in the actual implementation of the policy at run-time        try {            Class policyClass = Class.forName(POLICY_IMPL_CLASS_NAME);            sPolicy = (IPolicy)policyClass.newInstance();        //这里不能直接 sPolicy = new Policy();而必须要用反射的原因是Policy类的声明也是被隐藏的,尽量Policy类在"impl"子包中, 也必须使用反射才能找到, 不能直接import com.android.internal.policy.impl.Policy; 然后new Policy().        } catch (ClassNotFoundException ex) {            throw new RuntimeException(                    POLICY_IMPL_CLASS_NAME + " could not be loaded", ex);    }    // Cannot instantiate this class    private PolicyManager() {}    // The static methods to spawn new policy-specific objects    public static Window makeNewWindow(Context context) {        return sPolicy.makeNewWindow(context);    }    ...}
transient关键字

加transient关键字的属性, 不会被序列化, 比如银行卡密码等不希望在网络中传输, 就需要加上这个关键字.

public class SerializableCookie implements Serializable {        private static final long serialVersionUID = 6374381828722046732L;        private transient final Cookie cookie;        private transient BasicClientCookie clientCookie;}public class HashSet extends AbstractSet implements Set, Cloneable, Serializable {    static final long serialVersionUID = -5024744406713321676L;    private transient HashMap map;}
@SuppressWarings注解的作用

@SuppressWarings注解
作用:用于抑制编译器产生警告信息。
refer to : http://www.cnblogs.com/fsjohnhuang/p/4040785.html

@SuppressWarnings("UnusedDeclaration")public class StrictANRWatchDog extends Thread {//这个类中的某个方法如果没有被使用的话, IDE也不会给出警告信息, 免得代码看起来很繁乱.
什么时候用接口, 什么时候用抽象类.

abstract class中,可以有自己的数据成员,
abstract class中,可以有一部分abstarct成员方法, 其他的也可以是一般的成员方法(给出成员方法的实现).
interface中,一般不定义数据成员,如果定义的话, 也是public static final常量,且必须给其初值.
interface中,所有的成员方法都是abstract的,都没有方法的实现, 只是abstract关键字给省略了.

//abstract classpublic abstract class Reader implements Readable, Closeable {    protected Object lock;    protected Reader() {        lock = this;    }    public abstract void close() throws IOException;    public void mark(int readLimit) throws IOException {        throw new IOException();    }...}
// interfacepublic interface ResponseDelivery {    public void postResponse(Request<?> request, Response<?> response);    public void postResponse(Request<?> request, Response<?> response, Runnable runnable);    public void postError(Request<?> request, VolleyError error);}
什么是抽象类和匿名内部类,以及为什么要使用它们

什么是抽象函数
只有函数的定义, 没有函数体的函数被成为抽象函数.
abstract void eat();

什么是抽象类
使用abstract定义的类被称之为抽象类.

  1. 抽象类不能够生成对象, 但是却可以有构造函数, 提供给子类通过super()方法进行调用.
  2. 如果一个类当中包含有抽象函数, 那么这个类必须被声明为抽象类.
  3. 如果一个类中没有抽象函数, 那么这个类也可以被声明为抽象类.

为什么使用抽象类
架构设计的时候为什么要有意识的使用抽象类.
定义一个通用的打印机的基类.
方案1:

class Printer {    void open() {        System.out.println("open()");    }    void close() {        System.out.println("close()");    }    //这里给出一个空的方法体, 让具体的子类去override进行实现.    void print() {    }}

方案2:

abstract class Printer {    void open() {        System.out.println("open()");    }    void close() {        System.out.println("close()");    }    abstract void print(); //把print()定义为抽象方法.}

2个方案其实都能实现同样的功能.
抽象类中的抽象方法的设计价值是,通过编译器保证了子类确实对抽象方法进行了实现,如果用一个空函数体的方法代替抽象方法就无法通过编译器去保证子类对这个方法进行了实现.

什么是匿名内部类
匿名内部类的使用地方是:用在方法的参数,一般是new一个接口的对象出来使用.

handler.postDelayed(new Runnable() {    @Override    public void run() {            Log.i(TAG, "Sending file " + filename);            sendCrashData(context, filename, finalJavaCrashCountUploader);    }}, delayTime);

这里的new Runnable() {}就是一个匿名内部类的对象.

开发中要注意的点:
如果子类的构造方法中没有显示的调用父类构造方法,则系统默认调用父类无参数的构造方法.

class Chinese extends Person {    Chinese() {        System.out.println("Chinese的构造方法");    }        void eat() {        System.out.println("用筷子吃饭");    }}等同于:class Chinese extends Person {    Chinese() {        super();        System.out.println("Chinese的构造方法");    }        void eat() {        System.out.println("用筷子吃饭");    }}
volatile关键字修饰的变量, 对其操作为原子级.

有一个例外是, 如果当前值与该变量以前的值相关,
那么volatile关键字不起作用,也就是说如下的表达式都不是原子操作:

public static volatile int n = 0;n = n + 1;n++;

在这种情况下,可使用synchronized关键字实现对其变量操作的原子性.

public static int n = 0;public static synchronized void inc()  {          n++;  }  

详见:
http://developer.51cto.com/art/200906/132344.htm(初学Java多线程:慎重使用volatile关键字)

定义static内部类就相当于直接写了一个.java的文件

主要是防止内存泄露,使用static 相当于直接写了一个.java的文件,
与外部类就没有依赖关系了,详见
http://stackoverflow.com/questions/70324/java-inner-class-and-static-nested-class
普通内部类隐含有个成员变量this$0, 持有对外部类的引用, this$0变量在内部类的默认构造方法中, 用外部类对象对其进行的赋值.

StringBuffer和StringBuilder的区别

1.使用String类的场景:在字符串不经常变化的场景中可以使用String类,例如常量的声明、少量的变量运算。

2.使用StringBuffer类的场景:在频繁进行字符串运算(如拼接、替换、删除等),并且运行在多线程环境中,则可以考虑使用StringBuffer,例如XML解析、HTTP参数解析和封装。

3.使用StringBuilder类的场景:在频繁进行字符串运算(如拼接、替换、和删除等),并且运行在单线程的环境中,则可以考虑使用StringBuilder,如SQL语句的拼装、JSON封装等。

结论:
StringBuffer是线程安全的,有加锁开销,效率略低。StringBuilder非线程安全,不用加锁,效率更高。一般字符串相加不会有多线程操作,所以推荐使用StringBuilder.

很少碰到这种情况, StringBuilder sb = new StringBuilder(); 然后在2个线程中, 同时分别调用sb.append("abc")和sb.append("123"); 在这种情况下, 最终sb的结果就会不符合预期.

但很少使用多线程对一个字符串进行相加操作, 因此大多数情况下, 优先使用StringBuilder > StringBuffer.

JSONObject optString与getString的区别

getString(String name)与optString(String name),功能一样,只是当name key 不存在时,getString(String name)抛出异常错误,optString(String name)返回空值.

更多相关文章

  1. Android(安卓)Rxjava和retrofit
  2. LeakCanary-帮助你检测Android所有的内存泄漏
  3. Android(安卓)ListView CheckBox状态错乱解析
  4. Android(安卓)startService 和 bindService
  5. 我的Android进阶之旅------>Android颜色值(#AARRGGBB)透明度百分比
  6. Android去掉标题栏和状态栏的方法
  7. Android(安卓)动态图文混排的常用方法
  8. Android(安卓)Framework内核之旅
  9. Android工程报错常见解决方法

随机推荐

  1. Unity Android交互过坑指南
  2. Android SDK下载慢的最给力解决办法
  3. Android项目结构和AndroidManifest.xml
  4. Android 之 ContentProvider的简介-相关
  5. android仿美团底部导航栏的点击效果——
  6. 【Android】Android Studio 1.5+ 中混合
  7. Android 应用程序中使用 Internet 数据
  8. Android 用SlidingDrawer实现抽屉效果
  9. android小复习
  10. 学习Android 应注意的十个问题