当前位置: 首页 > news >正文

Fragment 知识梳理, FragmentPagerAdapter ,RecyclerView 知识梳理,sharepreference,IntentService,service交互

Fragment:

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

三种情况

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

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

 

RecyclerView 知识梳理:https://www.jianshu.com/p/21a1384df9a1

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

  • LayoutManagerposition the view
  • ItemAnimatoranimate the view
  • Adapterprovide the view

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

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

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

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

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

AsyncTask:

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

 

 

HandlerThread:https://www.jianshu.com/p/3d0ebbde4ffe

就是一个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 :https://www.jianshu.com/p/cd85472da155

这是 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);
    }
}

 

 

 

 

 

 

相关文章:

  • kotlin 学习,val和var的区别
  • kotlin ==和===区别,kotlin数组,kotlin 三引号,if-else 调监控子很语句,
  • CMake 进行 NDK 开发之初体验, Error occurred while communicating with CMake server
  • dump java heap,GPU,Lint
  • 处理屏幕旋转导致的重建,单例对象,StringBuilder进行拼接,ProGurad 混淆,VectorDrawable 及 AnimatedVectorDrawable,IntentService
  • SVG,Vector,gradle
  • 蓝牙通讯数据传输,蓝牙UUID,BluetoothAdapter;adb input 模拟系统输入,adb logcat:抓包,抓日志,蓝牙通讯,adb命令实现手机之间互相控制,虚拟按键
  • gradle中的 compileSdkVersion minSdkVersion targetSdkVersion
  • android 解决中文乱码,reload和cnvert区别
  • JetGradlePlugin,transformDexArchiveWithExternalLibsDexMergerForDebug
  • jcenter()和mavenCentral()区别
  • v4 v7包的使用,Android Gradle的理解,版本号对应Gradle发行版本
  • 程序员接私活
  • aapt问题,compileSdkVersion、buildToolsVersion、buildToolsVersion、 com.android.support:appcompat-v7版本问题
  • 幸存者偏差
  • [PHP内核探索]PHP中的哈希表
  • laravel 用artisan创建自己的模板
  • uni-app项目数字滚动
  • 记一次删除Git记录中的大文件的过程
  • 名企6年Java程序员的工作总结,写给在迷茫中的你!
  • 那些被忽略的 JavaScript 数组方法细节
  • 前言-如何学习区块链
  • 区块链将重新定义世界
  • 深入浅出Node.js
  • 推荐一款sublime text 3 支持JSX和es201x 代码格式化的插件
  • 小而合理的前端理论:rscss和rsjs
  • AI又要和人类“对打”,Deepmind宣布《星战Ⅱ》即将开始 ...
  • Mac 上flink的安装与启动
  • #pragma multi_compile #pragma shader_feature
  • #单片机(TB6600驱动42步进电机)
  • (二)WCF的Binding模型
  • (附源码)springboot家庭财务分析系统 毕业设计641323
  • .bat批处理(六):替换字符串中匹配的子串
  • .form文件_SSM框架文件上传篇
  • .net程序集学习心得
  • .NET多线程执行函数
  • .net访问oracle数据库性能问题
  • .NET中winform传递参数至Url并获得返回值或文件
  • .vimrc php,修改home目录下的.vimrc文件,vim配置php高亮显示
  • @ModelAttribute使用详解
  • [ vulhub漏洞复现篇 ] Django SQL注入漏洞复现 CVE-2021-35042
  • [AutoSar]BSW_Memory_Stack_004 创建一个简单NV block并调试
  • [BZOJ1040][P2607][ZJOI2008]骑士[树形DP+基环树]
  • [Eclipse] 详细设置护眼背景色和字体颜色并导出
  • [go] 策略模式
  • [java后端研发]——文件上传与下载(2种方式)
  • [NLP] LlaMa2模型运行在Mac机器
  • [POI2006] OKR-Periods of Words——最大周期长度(扩展最小周期长度)
  • [Python]—Linux Server 系统监控程序
  • [Python人工智能] 四十.命名实体识别 (1)基于BiLSTM-CRF的威胁情报实体识别万字详解
  • [RK3568 Android11] 时间同步机制
  • [WCF]重载
  • [WeChall]Training: Stegano I的解法
  • [Windows编程] DLL_THREAD_DETACH 认识误区
  • [Windows编程] Windows 7 对多核的支持