Android知识

2017-10-19  本文已影响0人  zhangweiheb

大部分引自:https://github.com/francistao/LearningNotes/blob/master/Part1/Android/Android%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86.md
外加自己写的一些

布局


Activity生命周期

Activity生命周期

Activity 启动模式

通过Activity的xml标签来改变任务栈的默认行为:

android:launchMode="standard|singleInstance|singleTask|singleTop"

任务栈是一种后进先出的结构。位于栈顶的Activity处于焦点状态,当按下back按钮的时候,栈内的Activity会一个一个的出栈,并且调用其onDestory()方法。如果栈内没有Activity,那么系统就会回收这个栈,每个APP默认只有一个栈,以APP的包名来命名。

Activity的堆栈管理以ActivityRecord为单位,所有的ActivityRecord都放在一个List里面,可以认为一个ActivityRecord就是一个Activity栈。


Activity状态缓存

有A、B两个Activity,当从A进入B之后一段时间,可能系统会把A回收,这时候按back,执行的不是A的onRestart而是onCreate方法,A被重新创建一次,这是A中的临时数据和状态可能就丢失了。
可以用Activity中的onSaveInstanceState()回调方法保存临时数据和状态,这个方法一定会在活动被回收之前调用。方法中有一个Bundle参数,putString()、putInt()等方法需要传入两个参数,一个键一个值。数据保存之后会在onCreate中恢复,onCreate也有一个Bundle类型的参数。
示例代码:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //这里,当Acivity第一次被创建的时候为空
        //所以我们需要判断一下
        if( savedInstanceState != null ){
            savedInstanceState.getString("anAnt");
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        outState.putString("anAnt","Android");

    }
  1. onSaveInstanceState (Bundle outState)
    当某个activity变得“容易”被系统销毁时,该activity的onSaveInstanceState就会被执行,除非该activity是被用户主动销毁的,例如当用户按BACK键的时候。
    注意上面的双引号,何为“容易”?言下之意就是该activity还没有被销毁,而仅仅是一种可能性。这种可能性有哪些?通过重写一个activity的所有生命周期的onXXX方法,包括onSaveInstanceState和onRestoreInstanceState方法,我们可以清楚地知道当某个activity(假定为activity A)显示在当前task的最上层时,其onSaveInstanceState方法会在什么时候被执行,有这么几种情况:

总而言之,onSaveInstanceState的调用遵循一个重要原则,即当系统“未经你许可”时销毁了你的activity,则onSaveInstanceState会被系统调用,这是系统的责任,因为它必须要提供一个机会让你保存你的数据(当然你不保存那就随便你了)。另外,需要注意的几点:

  1. onRestoreInstanceState (Bundle outState)
    至于onRestoreInstanceState方法,需要注意的是,onSaveInstanceState方法和onRestoreInstanceState方法“不一定”是成对的被调用的。
    onRestoreInstanceState被调用的前提是,activity A“确实”被系统销毁了,而如果仅仅是停留在有这种可能性的情况下,则该方法不会被调用,例如,当正在显示activity A的时候,用户按下HOME键回到主界面,然后用户紧接着又返回到activity A,这种情况下activity A一般不会因为内存的原因被系统销毁,故activity A的onRestoreInstanceState方法不会被执行。
    另外,onRestoreInstanceState的bundle参数也会传递到onCreate方法中,你也可以选择在onCreate方法中做数据还原。 还有onRestoreInstanceState在onstart之后执行。 至于这两个函数的使用,给出示范代码(留意自定义代码在调用super的前或后):
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    savedInstanceState.putBoolean("MyBoolean", true);
    savedInstanceState.putDouble("myDouble", 1.9);
    savedInstanceState.putInt("MyInt", 1);
    savedInstanceState.putString("MyString", "Welcome back to Android");
    // etc.
    super.onSaveInstanceState(savedInstanceState);
}

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);

    boolean myBoolean = savedInstanceState.getBoolean("MyBoolean");
    double myDouble = savedInstanceState.getDouble("myDouble");
    int myInt = savedInstanceState.getInt("MyInt");
    String myString = savedInstanceState.getString("MyString");
}

处理运行时变更

https://developer.android.com/guide/topics/resources/runtime-changes.html?hl=zh-cn


Fragment生命周期

Fragment生命周期

注意和Activity的相比的区别,按照执行顺序


Fragment与Activity生命周期关系

Fragment与Activity生命周期关系

为什么在Service中创建子线程而不是Activity中

这是因为Activity很难对Thread进行控制,当Activity被销毁之后,就没有任何其它的办法可以再重新获取到之前创建的子线程的实例。而且在一个Activity中创建的子线程,另一个Activity无法对其进行操作。但是Service就不同了,所有的Activity都可以与Service进行关联,然后可以很方便地操作其中的方法,即使Activity被销毁了,之后只要重新与Service建立关联,就又能够获取到原有的Service中Binder的实例。因此,使用Service来处理后台任务,Activity就可以放心地finish,完全不需要担心无法对后台任务进行控制的情况。


Intent的使用方法,可以传递哪些数据类型

通过查询Intent/Bundle的API文档,我们可以获知,Intent/Bundle支持传递基本类型的数据和基本类型的数组数据,以及String/CharSequence类型的数据和String/CharSequence类型的数组数据。而对于其它类型的数据貌似无能为力,其实不然,我们可以在Intent/Bundle的API中看到Intent/Bundle还可以传递Parcelable(包裹化,邮包)和Serializable(序列化)类型的数据,以及它们的数组/列表数据。


Service两种启动方法和区别

  1. 通过 Context 的
public boolean bindService(Intent service,ServiceConnection conn,int flags)

方法来进行Service与Context的关联并启动,并且Service的生命周期依附于Context(不求同时同分同秒生!但求同时同分同秒屎!!)。

  1. 通过
public ComponentName startService(Intent service)

方法去启动一个Service,此时Service的生命周期与启动它的Context无关。


广播(Broadcast Receiver)的两种动态注册和静态注册有什么区别


如何保证Service不被杀死


动画类型


Android的数据存储形式


如何判断应用被强杀

在Application中定义一个static常量,赋值为-1,在欢迎界面改为0,如果被强杀,application重新初始化,在父类Activity判断该常量的值。


应用被强杀如何解决

如果在每一个Activity的onCreate里判断是否被强杀,冗余了,封装到Activity的父类中,如果被强杀,跳转回主界面,如果没有被强杀,执行Activity的初始化操作,给主界面传递intent参数,主界面会调用onNewIntent方法,在onNewIntent跳转到欢迎页面,重新来一遍流程。


asset目录与res目录的区别

res 目录下面有很多文件,例如 drawable,mipmap,raw 等。res 下面除了 raw 文件不会被压缩外,其余文件都会被压缩。同时 res目录下的文件可以通过R 文件访问。Asset 也是用来存储资源,但是 asset 文件内容只能通过路径或者 AssetManager 读取。


Android怎么加速启动Activity

分两种情况,启动应用 和 普通Activity 启动应用 :Application 的构造方法,onCreate 方法中不要进行耗时操作,数据预读取(例如 init 数据) 放在异步中操作 启动普通的Activity:A 启动B 时不要在 A 的 onPause 中执行耗时操作,因为 B 的 onResume 方法必须等待 A 的 onPause 执行完成后才能运行。


Android内存优化方法

ListView优化,及时关闭资源,图片缓存等等。


Android中软引用与弱引用的应用场景

http://www.jianshu.com/p/8488079a939b

    View view = findViewById(R.id.button);
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher);
    Drawable drawable = new BitmapDrawable(bitmap);
    SoftReference<Drawable> drawableSoftReference = 
                                                new SoftReference<Drawable>(drawable);
    if(drawableSoftReference != null) {
        view.setBackground(drawableSoftReference.get());
    }
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import java.lang.ref.WeakReference;

public class MainActivity extends AppCompatActivity {

    private Handler handler  ;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        handler = new MyHandler( this ) ;

        new Thread(new Runnable() {
            @Override
            public void run() {
               handler.sendEmptyMessage( 0 ) ;
            }
        }).start() ;

    }

    private static class MyHandler extends Handler {
        WeakReference<MainActivity> weakReference ;

        public MyHandler(MainActivity activity ){
            weakReference  = new WeakReference<MainActivity>( activity) ;
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if ( weakReference.get() != null ){
                // update android ui
            }
        }
    }

}

在Android应用的开发中,为了防止内存溢出,在处理一些占用内存大而且声明周期较长的对象时候,可以尽量应用软引用和弱引用技术。
软引用,弱引用都非常适合来保存那些可有可无的缓存数据。如果这样做,当系统内存不足时,这些缓存数据会被回收,不会导致内存溢出。而当内存资源充足时,这些缓存数据又可以存在相当长的时间。


Bitmap四种属性


View与ViewGroup

自定义View过程:onMeasure()、onLayout()、onDraw()
如何自定义控件:

  1. 自定义属性的声明和获取
    • 分析需要的自定义属性
    • 在res/values/attrs.xml定义声明
    • 在layout文件中进行使用
    • 在View的构造方法中进行获取
  2. 测量:onMeasure
  3. 布局:onLayout(ViewGroup)
  4. 绘制:onDraw
  5. onTouchEvent
  6. onInterceptTouchEvent(ViewGroup)
  7. 状态的恢复与保存

View树绘制流程

http://www.jianshu.com/p/5a71014e7b1b


下拉刷新实现原理

http://blog.csdn.net/guolin_blog/article/details/9255575


Android长连接

心跳:Android微信智能心跳方案.


Context区别


IntentService使用场景与特点

IntentService是Service的子类,是一个异步的,会自动停止的服务,很好解决了传统的Service中处理完耗时操作忘记停止并销毁Service的问题。
特点:

onStartCommand中回调了onStart,onStart中通过mServiceHandler发送消息到该handler的handleMessage中去。最后handleMessage中回调onHandleIntent(intent)。


Android 5.0、6.0、7.0 特性

上一篇 下一篇

猜你喜欢

热点阅读