Fragment:
会保存左右各一个界面,采用栈存储信息,page1234,从2开始滑动到3,会删除1,添加4,从OnCreateview开始OnDestoryView结束。第一次添加会从生命周期开始走,OnCreate。
三种情况
- 第一次添加
- 重新添加
- 移除
此时,它们内部的Fragment
所走的生命周期为:
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 startId) { Log.e(TAG, "onStartCommand: !!!!!!"); return super.onStartCommand(intent, flags, startId); } /** * 服务启动时调用 */ @Override public void onStart(@Nullable Intent intent, int startId) { super.onStart(intent, startId); Log.e(TAG, "onStart: !!!!!!!!"); } /** * 这个方法是在工作线程里执行的 */ @Override protected void onHandleIntent(@Nullable Intent intent) { 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 startId) { 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); } }