ThinkSlow

Results 20 issues of ThinkSlow

### 前言 `AsyncTask`、`HandlerThrad`、`IntentService`都是对Android消息机制的封装和应用,解决在子线程耗时任务,主线程更新UI的问题。 ### AsyncTask的使用 AsyncTask是一个抽象类,通过子类继承重写`doInBackground`,该方法在子线程运行。 ``` public class DownloadTask extends AsyncTask { @Override protected void onPostExecute(String s) { super.onPostExecute(s); } @Override protected String doInBackground(String... strings) { publishProgress(1); return "AsyncTask";...

## 前言 在Android中,主线程与子线程的交互,例如在子线程进行网络请求,请求后将数据更新到View上,我们常用Handler或者AsyncTask。HandlerThread与它们的区别在于会创建工作线程、Hanlder和Looper。这样就不用在主线程创建Handler或者AsyncTask的硬性要求。可以说HandlerThread是Handler的应用场景。 ## HandlerThread的使用 HandlerThread继承至Thread,所以本身也是一个线程。先撸代码为敬,下面是一般例子代码。 ``` HandlerThread handlerThread = new HandlerThread("handler"); handlerThread.start(); Handler workerHandler = new Handler(handlerThread.getLooper()) { @Override public void handleMessage(Message msg) { super.handleMessage(msg); //doSomething } }; workerHandler.post(new...

在`Android`的四大组件中,`Service`排行老二,在`Android`中的主要作用是后台服务,进行与界面无关的操作。由于`Service`运行在主线程,所以进行异步操作需要在子线进行。为此`Android`为我们提供了`IntentService`。 `IntentService`是一个抽象类,继承至`Service`,主要方便我们新建工作线程进行异步操作。提交任务到`IntentService`时,异步任务以串行方式进行处理,意味着工作线程一次只处理一个任务。而且当所有任务都完成之后,会自动停止`Service`,不需要我们手动停止。 ### IntentService 的使用 1. 我们定义`DownloadService`类并继承至`IntentService`。来模拟网络下载的过程。 ``` public class DownloadService extends IntentService { private static int count = 0; /** * 主要用于调用服务类构造器 * * @param name 用于区分不同任务 */ public...

以注重生命周期的方式管理和界面相关的数据,Jetpack为我们带来了ViewModel,从本文你可以学习到使用ViewModel的正确姿势 ## 一、ViewModel ViewModel被用来以注重生命周期的方式来保存数据和管理界面相关的数据。同时可以在相关配置发生变化是保存数据,例如屏幕旋转。 由于Android framework管理着像Activity、Fragment这样具有生命周期的UI控制器,所以在用户的某些操作或者系统分发的某些事件,会导致framework在没有经过我们控制下,销毁和重建UI控制器。例如,屏幕发生旋转时,framwork会调用Activity的`onSaveIntanceState()`保存数据,在新Activity的`onCreate()`方法中恢复这些数据,不过这仅仅是恢复可序列化和反序列化的小数据上,像list或者bitmap这种大数据就不合适了。此外,也会导致大量已经存在的数据被销毁,然后重新生成,造成资源的浪费。 在`LiveData`也说到,不要在Activity和Fragment做大量的逻辑操作,会导致代码臃肿,难以维护,建议把相关逻辑抽到单独的类进行维护,让UI控制器负责它们的本质工作。 为此,使用ViewModel可以轻松解决以上问题。 ### 1. 实现ViewModel Architecture Components提供ViewModel工具类,用来为UI提供数据。ViewModel对象在配置发生变化时会自动保存数据,并且会在新建的Activity或Fragment实例使用。例如,在APP中需要显示持有多个user对象的list,应该将请求和保存users数据的动作在ViewModel对象实现,而不是Activity或Fragment。 ``` class MyViewModel : ViewModel() { private val users: MutableLiveData by lazy { MutableLiveData().also { loadUsers() }...

学习网络编程先要学习相关网络基础协议,而网络协议是一套规定了两个终端之间如何进行连接和数据交互的集合。 ## 1.常见网络分层 不管是OSI七层模型还是TCP/IP的四层、五层模型,每一层中都要自己的专属协议,完成自己相应的工作以及与上下层级之间进行沟通。 ![](https://user-gold-cdn.xitu.io/2019/6/27/16b98a73a13109cc?w=719&h=541&f=png&s=34033) ### 1.1 应用层 也包括:表示层和会话层 为操作系统或网络应用程序提供访问网络服务的接口。常用的HTTP协议就是在此层,另外还有FTP、Telnet、DNS、SMTP,POP3等协议。 ### 1.2 传输层 第一个端到端,即主机到主机的层次。传输层负责将上层数据分段并提供端到端的、可靠的或不可靠的传输。此外,传输层还要处理端到端的差错控制和流量控制问题。著名的TCP、UDP协议就位于此。 ### 1.3 网络层 第一个端到端,即主机到主机的层次。传输层负责将上层数据分段并提供端到端的、可靠的或不可靠的传输。此外,传输层还要处理端到端的差错控制和流量控制问题。主要协议有IP协议,ICMP协议,ARP协议,RARP协议。 ### 1.4 网络接口层 数据链路层在物理层提供的服务的基础上向网络层提供服务,其最基本的服务是将源自网络层来的数据可靠地传输到相邻节点的目标机网络层。 物理层具有激活、维持、关闭通信端点之间的机械特性、电气特性、功能特性以及过程特性。主要协议有以太网协议。 ## 2. HTTP与HTTPS协议 先提个醒,Android 9.0默认是不能进行Http网络请求的,所以在适配Android 9.0的时候记得添加配置文件,让其可以进行HTTP网络请求。 ###...

### 前言 `Android` 的消息机制原理是`Android`进阶必学知识点之一,在`Android`面试也是常问问题之一。在`Android`中,子线程是不能直接操作`View`,需要切换到主线程进行。那么这个切换动作就涉及到了`Android`的消息机制,也就是本文要讲的Handler、Looper、MessageQueue、Message它们之间的关系。 ### Handler `Handler`在消息机制中扮演**发送消息**和**处理消息**的角色,也是我们平常接触最多的类。 #### Handler如何处理消息? 下面代码展示`Handler`如何处理消息。新建`Handler`对象,并重写handleMessage,在方法内处理相关逻辑,一般处理和主线程相关的逻辑。Handler有很多的构造器,下面构造器常用在主线程。 ``` private Handler handler=new Handler(){ @Override public void handleMessage(Message msg) { if (msg.what==1){ Toast.makeText(MainActivity.this,"handle message",Toast.LENGTH_LONG).show(); } } }; ``` ####...

为什么需要我们管理Activity和Fragment的生命周期?这些不是Framework自动帮我们搞定的么?(手动黑人问号)刚看到这样的标题我也是很懵逼,不就是onCreate->onSart()->onResume()->onPause()->onStop()->onDestory()么?难道还有什么高深的地方么? ## Abount Lifecycle-Aware Components 该组件能在像Activity、Fragment等等具有生命周期的组件发生状态改变时,以轻量级的和易维护的代码作出响应动作。 吃个栗子就懂意思了: ``` //为了考虑大多数同学学习过Java,就贴Java的代码 //定义个监听类,用来在Activity生命周期发生变化时,对定位服务资源作相关处理 class MyLocationListener { public MyLocationListener(Context context, Callback callback) { // ... } void start() { // connect to system location...

又到周末好时光,开始嗨之前再抽点时间看看本文,能看到最后的都是大佬,收下我的膜拜。本文技术内容讲的是关于Data Binding Library的那点事,有的同学可能解过了,有的娃可能都不知道是什么东东...。为了不落伍,和大家一样优秀,决定写Jetpack方面的文章。与别人不一样的是,会加入自己的理解和栗子,而不是简单的翻译(我英文水平也不行)。如果大家发现有误的地方,希望多加指点,在此谢过。 ## About Jetpack 一年前有缘看了一下Jetpack,但并没有过多的去关注,最近在看Google IO 2019相关资料,看到了Jetpack的身影,不得不陷入深思,无法自拔。 #### JetPack的官方说法: Jetpack 是 Android 软件组件的集合,使您可以更轻松地开发出色的 Android 应用。这些组件可帮助您遵循最佳做法、让您摆脱编写样板代码的工作并简化复杂任务,以便您将精力集中放在所需的代码上。 #### 总结性 * 加速开发:以组件的形式供我们依赖使用。 * 消除样板代码:还记得在`Activity`中一大堆`findViewById`么?能做的不止这么多。 * 构建高质量应用:现在化设计、避开bug、向后兼容。 Android Jetpack 组件是库的集合,这些库是为协同工作而构建的,不过也可以单独采用,同时利用 Kotlin 语言功能帮助提高工作效率。可全部使用,也可混合搭配!...

又到周末好时光,茫茫人海中,与你在掘金相遇,好幸运~请君珍惜缘分,赏阅本文。相处不易,开门见山,不扯皮。本文讲的是Jetpack系列第三个架构组件LiveData,LiveData是Lifecycle-aware 组件的一个应用,这意味着LiveData遵守Activity、Fragment和Service等组件的生命周期,在它们生命周期处于活跃状态(`CREATED`和`RESUMED`)才进行更新Views。 ### 使用LiveData步骤 1. 创建持有某种类型的LiveData对象。通常在ViewModel类来实现该对象。 2. 定义一个具有onChanged()方法的Observer对象,当LiveData持有数据变化是回调该方法。通常在UI控制器类中实现创建该Observer对象,如Activity或Fragment。 3. 通过使用observe()方法,将上述的LiveData对象和Observer对象关联在一起。这样Observer对象就与LiveData产生了订阅关系,当LiveData数据发生变化时通知,而在Observer更新数据,所以Observer通常是Activity和Fragment。 三个步骤就定义了使用LiveData的方式,从步骤可以看出,使用了观察者模式,当LiveData对象持有数据发生变化,会通知对它订阅的所有处于活跃状态的订阅者。而这些订阅者通常是UI控制器,如Activity或Fragment,以能在被通知时,自动去更新Views。 ### 创建LiveData对象 LiveData可以包装任何数据,包括集合对象。LiveData通常存储在ViewModel中,并通过getter方法获得。示例: ``` class NameViewModel : ViewModel() { // Create a LiveData with a String val currentName: MutableLiveData...

## 1. 前言 ConstraintLayout入门到深入,如果看不完还不会,我手把手教你.. ## 2. ConstraintLayout ConstraintLayout作为一款可以灵活调整view位置和大小的Viewgroup被Google疯狂推荐,以前创建布局,默认根元素都是LinearLayout,现在是ConstraintLayout了。ConstraintLayout能够以支持库的形式最小支持到API 9,同时也在不断的丰富ConstraintLayout的API和功能。ConstraintLayout在复杂布局中能够有效的,降低布局的层级,提高性能,使用更加灵活。 在app组件的Graldle默认都有如下依赖: ``` //可能版本不一样哦 implementation 'com.android.support.constraint:constraint-layout:1.1.3 ``` 迫不及待想了解ConstraintLayout能在布局做点什么了。 ### 2.1 相对定位 相对定位,其实这跟RelativeLayout差不多,一个View相对另外一个View的位置。 ![相对布局](https://user-gold-cdn.xitu.io/2019/6/26/16b917703d745c01?w=270&h=232&f=png&s=23297) 通过简单的使用ConstraintLayout的属性也就可以实现以上布局。World对于Hello的右边,GitCode对位于Hello的下边 ``` ``` 以TextView World相对位置属性layout_constraintLeft_toRightOf来说,constraintLeft表示TextView World本身的左边,一个View有四条边,因此TextView的上、右、下边分别对应着constraintTop、constraintRight、constraintBottom。toRightOf则表示位于另外一个View的右边,例如此处位于Hello的右边,因此对应还有toLeftOf、toRghtOf、toBottomOf,分别位于View Hello的左、右、下边。总结的说,constraintXXX表示View自身约束的边,toXXXOf表示另一个View的边,而XXX的值可以是Left、Top、Right、Bottom,分别对应左,上、右、下边。`layout_constraintStart_toEndOf`也是类似的道理。 另外需要注意的是,view的位置可以相对于同层的view和parent,在相对于parent的时候toLeftOf、toTopOf、toRghtOf、toBottomOf分别表示位于parent的内部左上右下边缘。如图:红色框表示parent view。...