Fragment:

会保存左右各一个界面,采用栈存储信息,page1234,从2开始滑动到3,会删除1,添加4,从OnCreateview开始OnDestoryView结束。第一次添加会从生命周期开始走,OnCreate。

三种情况

  • 第一次添加
  • 重新添加
  • 移除

此时,它们内部的​​Fragment​​所走的生命周期为:

Fragment 知识梳理, FragmentPagerAdapter ,RecyclerView 知识梳理,sharepreference,IntentSer_xml文件

​编辑

RecyclerView 知识梳理:www.jianshu.com/p/21a1384df…

整个​​RecyclerView​​体系包含三大组件:

  • ​LayoutManager​​​:​​position the view​
  • ​ItemAnimator​​​:​​animate the view​
  • ​Adapter​​​:​​provide the view​

这三大组件各司其职,而​​RecyclerView​​​负责管理,就组成了整个​​RecyclerView​​的架构。

​LayoutManager​​需要负责以下几部分的工作:

  • ​Position​​​ 它负责​​View​​的摆放,可以是线性、宫格、瀑布流式或者任意类型,而​​RecyclerView​​不知道也不关心这些,这是​​LayoutManager​​的职责。
  • ​Scroll​​​ 对于滚动事件的处理,​​RecyclerView​​负责接收事件,但是最终还是由​​LayoutManager​​进行处理滚动后的逻辑,因为只有它在知道​​View​​具体摆放的位置。
  • ​Focus traversal​​​ 当焦点转移导致需要一个新的​​Item​​出现在可视区域中时,也是由​​LayoutManager​​处理的。

​Adapter​​需要负责以下几部分的工作:

  • 创建​​View​​​和​​ViewHolder​​,后者作为整个复用机制的跟踪单元。
  • 把具体位置的​​Item​​​和​​ViewHolder​​进行绑定,并存储相关的信息。
  • 通知​​RecyclerView​​数据变化,支持局部的更新,在提高效率的同时也有效地支持了动画。
  • ​Item​​点击事件的处理。
  • 多类型布局的支持。

AsyncTask:

  • 静态方法​​execute(Runnable runnable)​​​和​​AsyncTask​​​其实没什么太大关系,只是用到了里面一个静态的线程池而已,​​AsyncTask​​内部的状态都和它无关。
  • 当我们对同一个​​AsyncTask​​​实例调用​​execute(..)​​时,如果此时已经有任务正在执行,或者已经执行过任务,那么会抛出异常。
  • 在​​onPreExecute()​​执行时,任务还没有被加入到队列当中。
  • ​doInBackground​​​是在子线程当中执行的,我们调用​​cancel​​​后,并不一定会立即得到​​onCancel​​​的回调,这是因为​​cancel​​​只保证了​​mFuture​​​的​​done​​方法被执行,有这么几种情况:
  • 关于​​AsyncTask​​​最大的问题其实是内存泄漏,因为把它作为​​Activity​​​的内部类时,会默认持有​​Activity​​​的引用,那么这时候如果有任务正在执行,那么 Activity 是无法被销毁的,这其实和​​Handler​​​的泄漏类似,可以有以下这么一些用法:不让它持有​​Activity​​​的引用或者持有弱引用。        保证在​​Activity​​​在需要销毁时​​cancel​​​了所有的任务。      使​​AsyncTask​​​的执行与​​Activity​​​的生命周期无关,可以考虑通过建立一个没有​​UI​​​的​​fragment​​​来实现,因为在​​Activity​​​重启时,会自动保存有之前​​add​​​进去的​​Fragment​​​的实例,​​Fragment​​​持有的还是先前的​​AsyncTask​​​。        使用​​LoaderManager​​,把管理的活交给系统来执行。

HandlerThread:​​www.jianshu.com/p/3d0ebbde4…​

就是一个​​Thread​​​,只不过可以通过它的​​getLooper​​​返回的​​Looper​​​作为​​Handler​​​构造函数的参数,那么这个新建​​Handler​​​所有​​message​​​的执行都是在这个对应的​​Thread​​当中的.

sharepreference:

获取sp对象,实际就是新建xml文件,之后异步线程进行xml文件读写操作,由于是xml文件因此程序关闭后xml文件仍然存在。持久化存储了。

  • 与某个​​name​​​所对应的​​SP​​​对象需要等到调用​​getSharedPreferences​​才会被创建
  • 对于同一进程而言,在​​Activity/Application/Service​​​获取​​SP​​​对象时,如果​​name​​​相同,它们实际上获取到的是同一个​​SP​​对象
  • 由于使用的是静态容器来保存,因此即使​​Activity/Service​​​销毁了,它之前创建的​​SP​​​对象也不会被释放,而​​SP​​​中的数据又是用​​Map​​​来保存的,也就是说,我们只要调用了某个​​name​​​相关联的​​getSharedPreferences​​​方法,那么和该​​name​​​对应的​​xml​​文件中的数据都会被读到内存当中,并且一直到进程被结束。
  • ​SP​​​在进程中是实际上是一个单例模式,因此,我们可以做到在进程中的任何地方改变​​SP​​的数据,都能收到监听。

IntentService :​​www.jianshu.com/p/cd85472da…​

这是 Service 的子类,它使用工作线程逐一处理所有启动请求。如果您不要求服务同时处理多个请求,这是最好的选择。 您只需实现 onHandleIntent() 方法即可,该方法会接收每个启动请求的 Intent,使您能够执行后台工作。

例子:

public class CustomService extends IntentService {
private static final String TAG = "CustomService>>>>>>>";

/**
* name是命名工作线程的,对debug有帮助
*/
public CustomService(String name) {
super(name);
}

public CustomService() {
super("hello");
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}

/**
* 服务创建时调用,服务正在运行不会调用
*/
@Override
public void onCreate() {
super.onCreate();
Log.e(TAG, "onCreate: !!!!!!!!!!!!");
}

/**
* 其它组件通过startServer后调用
*/
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int {
Log.e(TAG, "onStartCommand: !!!!!!");
return super.onStartCommand(intent, flags, startId);
}

/**
* 服务启动时调用
*/
@Override
public void onStart(@Nullable Intent intent, int {
super.onStart(intent, startId);
Log.e(TAG, "onStart: !!!!!!!!");
}

/**
* 这个方法是在工作线程里执行的
*/
@Override
protected void onHandleIntent(@Nullable {
Log.e(TAG, "onHandleIntent: 当前线程:" + Thread.currentThread().getName());
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
System.out.println("服务后台计数:》》" + i);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
}
}

/**
* 服务销毁前的回调
*/
@Override
public void onDestroy() {
super.onDestroy();
System.out.println("服务已完成!");
}
}


service交互:startService 下的交互

通过​​startService​​​启动服务的时候,只能通过​​onStartCommand​​​当中的​​Intent​​​进行交互,​​Service​​​根据​​Intent​​​中的​​action​​​区分行为,​​intent​​的数据作为输入参数。

这种方式的优点是 简单,缺点是 这种通信方式是单向的,只能由调用者告诉​​Service​​​做什么,​​Service​​无法返回给调用者信息。

public class CommandWorkerService extends Service {

private static final String TAG = CommandWorkerService.class.getSimpleName();

public static final String ACTION_LOG = "com.android.action.log";
public static final String ACTION_KEY_LOG_MSG = "com.android.action.log.msg";

@Override
public int onStartCommand(Intent intent, int flags, int {
handleIntent(intent);
return super.onStartCommand(intent, flags, startId);
}

private void handleIntent(Intent intent) {
String action = intent.getAction();
if (!TextUtils.isEmpty(action)) {
switch (action) {
case ACTION_LOG:
Log.d(TAG, intent.getStringExtra(ACTION_KEY_LOG_MSG));
break;
default:
break;
}
}
}

}


调用者的处理方式:

public class MainActivity extends AppCompatActivity {


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

@Override
protected void onDestroy() {
super.onDestroy();
stopService();
}

private void startService() {
Intent intent = new Intent(this, CommandWorkerService.class);
intent.setAction(CommandWorkerService.ACTION_LOG);
intent.putExtra(CommandWorkerService.ACTION_KEY_LOG_MSG, "Call CommandWorkerService");
startService(intent);
}

private void stopService() {
Intent intent = new Intent(this, CommandWorkerService.class);
stopService(intent);
}
}