【android】getDimension()、getDimensionPixelOffset()和getDimensionPixelSize()区别
使用java代码获取在xml中定义的尺寸:
- getDimension():基于当前DisplayMetrics进行转换,获取指定资源id对应的尺寸。函数的返回值是float。
- getDimensionPixelOffset():与getDimension()功能类似,不同的是将结果转换为int,并且小数部分四舍五入。
- getDimensionPixelSize():与getDimension()功能类似,不同的是将结果转换为int,并且直接截断小数位,即取整。
在类TypedArray和类Resource中都有这三个函数,功能类似,TypedArray中的函数是获取自定义属性的,Resource中的函数是获取android预置属性的
android:clipToPadding
该属性定义了ViewGroup是否将裁剪它的子View,和根据它的padding(如果padding不为0)调整任何边缘效果。默认值true。
关联方法:setClipToPadding(boolean)
意思是控件的绘制区域是否在padding里面
ListView顶部默认有一个顶部view,向上滑动后,覆盖顶部view显示:
android:indeterminate
不明确(false)就是滚动条的当前值自动在最小到最大值之间来回滚动,形成一个动画效果;
明确(true)就是根据你的进度可以设置现在的进度值。
Android中invalidate()函数
invalidate()是用来刷新View的,必须是在UI线程中进行工作。invalidate()的调用是把之前旧的view从主UI线程队列中pop掉。
请求重绘View树,即draw()过程,假如视图大小没有发生变化就不会调用layout()过程,并且只绘制那些“需要重绘的”视图,即谁(View的话,只绘制该View;ViewGroup,则绘制整个ViewGroup)请求invalidate()方法,就绘制该视图。
一般引起invalidate()操作的函数如下:
-
直接调用invalidate()方法,请求重新draw(),但只会绘制调用者本身。
-
setSelection()方法:请求重新draw(),但只会绘制调用者本身。
-
setVisibility()方法:当View可视状态在INVISIBLE转换VISIBLE时,会间接调用invalidate()方法,继而绘制该View。
-
setEnabled()方法:请求重新draw(),但不会重新绘制任何视图包括调用者本身。
java.time.Duration.ofHours()方法
java.time.Duration.ofHours(long hours)方法获取表示多少个标准小时数的持续时间。
以下示例显示了此方法的用法
import java.time.Duration; public class DurationDemo { public static void main(String[] args){ Duration duration = Duration.ofHours(2); System.out.println(duration.getSeconds()); } } //7200
java.time.LocalTime.minusHous(long hoursToSubtract)方法
方法返回LocalTime的副本,并减去指定的小时数。
示例
import java.time.LocalTime;
public class LocalTimeDemo {
public static void main(String[] args) {
LocalTime time = LocalTime.parse("12:30:30");
System.out.println(time.minusHours(2));
}
}
//10:30:30
Android剪切板 ClipboardManager,ClipData
Android剪贴板框架主要涉及到ClipboardManager、ClipData、ClipData.Item、ClipDescription这四个类:
-
ClipboardManager:是系统全局的剪贴板对象,通过context.getSystemService(CLIPBOARD_SERVICE)获取。
-
ClipData,即clip(剪切)对象,在系统剪贴板里只存在一个,当另一个clip对象进来时,前一个clip对象会消失。
-
ClipData.Item,即data item,它包含了文本、Uri或者Intent数据,一个clip对象可以包含一个或多个item对象。通过addItem(ClipData.Item item)可以实现往clip对象中添加item。
- 文本text:文本是直接放在clip对象中,然后放在剪贴板里;粘贴这个字符串的时候直接从剪贴板拿到这个对象,把字符串放入你的应用存储中。
- Uri:表示任何形式的URI,这种形式主要用于从一个content provider中复制复杂的数据。复制的时候把一个Uri对象放在一个clip对象中,然后再放在剪贴板里;粘贴的时候取出这个clip对象,得到Uri,把它解析为一个数据资源比如content provider,然后从资源中复制数据到应用存储中。
- Intent:复制的时候Intent会被直接放入clip对象,这相当于拷贝了一个快捷方式。
-
ClipDescription,即clip metadata,它包含了clipData对象的metadata信息。可以通过getMimeType(int index)获取(一般index=0)
MimeType一般有以下四种类型:
// 对应 ClipData.newHtmlText(label, text, htmlText) 的 MimeType public static final String MIMETYPE_TEXT_HTML = "text/html"; // 对应 ClipData.newIntent(label, intent) 的 MimeType public static final String MIMETYPE_TEXT_INTENT = "text/vnd.android.intent"; // 对应 ClipData newPlainText(label, text) 的 MimeType public static final String MIMETYPE_TEXT_PLAIN = "text/plain"; // 对应 ClipData newPlainText(label, text) 的 MimeType public static final String MIMETYPE_TEXT_URILIST = "text/uri-list";
@NotNull和@NonNull区别和使用
@NotNull使用在Bean的字段注解中。在controller的方法中验证时使用(运行时检查一个属性是否为空),如果为空,注解中的提示信息会保存在result中。
@NonNull在方法或构造函数的参数上使用,生成一个空值检查语句。用于指明所修饰的参数、字段或方法的值不可以为null。当代码检查(静态检查)有空值时会给出一个风险警告,运行时不报任何警告。
View.INVISIBLE和View.GONE区别
View的setVisibility有三个值可以设置:
- VISIBLE–可见
- INVISIBLE–不可见,但这个View在ViewGroup中仍保留它的位置,不重新layout
- GONE–不可见,但这个View在ViewGroup中不保留位置,重新layout。
Android属性设置android:noHistory=“true”
⭕️设置该属性后,该Activity在stack中不留历史痕迹。默认值是false。
Android中Bundle类的作用
Bundle类用作携带数据,它类似与Map,用于存放key-value名值对形式的值。相对于Map,它提供了各种常用类型的putXxx()/getXxx()方法。Bundle的内部实际上是使用了HashMap类型的变量来存放值。
用于不同Activity之间的数据传递。
👽与SharedPreference的区别:SharedPreference是简单的存储持久化的设置,就像用户每次打开应用程序时的主页,它只是一些简单的键值对来操作,它将数据保存在一个xml文件中。
👽Bundle是将数据传递到另一个上下文中或保存或回复你自己状态的数据存储方式。它的数据不是持久化状态。
AccountManager
AccountManager账号管理器,集中管理apps注册的不同类型的账号。
不同类型的账号服务会使用不同的账号登录和鉴权方式,所以AccountManager为不同类型的账号提供一个插件式authenticator模块,authenticators自己处理账号登录/认证的具体细节,也可以自己存储账号信息
这个类给用户提供了集中注册账号的接口。用户仅仅要输入一次账户password后,就能够访问Internet资源。
不同的在线服务用不同的方式管理用户,所以accountmanager为不同类型的账户提供了统一验证管理的方法,处理有效的账户的具体信息而且实现排序。
AccountManager能够为应用生成tokens,这样应用就不需要直接处理password。tokens是能够被复用的而且由AccountManager缓存,可是必须周期性的刷新。应用程序必须在停止工作时丢弃tokens以便让AccountManager知道需要又一次生成tokens。
AccountManager使用步骤:
💛第一,获得AccountManager实例
AccountManager.get(context)
💛第二,使用**getAccountsByType(String)或getAccountsByTypeAndFeatures(String, String[], AccountManagerCallback, Handler)**获得可用的账户
Account[] accounts = AccountManager.get(context).getAccountsByType("com.google");
Android中Looper
Looper是Android为线程间异步消息通信提供的一种机制,利用Looper机制可以方便我们实现多线程编程时线程间的相互沟通。Looper的实现是利用消息队列的方式,为用户封装了一层API,用户不需要考虑互斥加锁的问题,方便用户的使用。
Handler、MessageQueue、Looper三者间的关系如图:
从上图可以看出,Handler发送线程消息到当前线程的MessageQueue中,而Looper用来管理MessageQueue,它从MessageQueue中取到消息交给handler处理。
Looper,通常运行在一个消息的循环队列中,线程在默认的情况下,不会给我们提供一个消息循环去管理消队列的。如果想管理消息队列,需要在线程中调用**Looper.prepare()方法使消息循环初始化,并且调用Looper.loop()**使消息循环一直处于运行状态,直到停止循环。所以Looper主要就是完成MessageQueue与Handler进行交互的功能。
在Activity的UI主线程中,无需使用显式的方式进行Looper的初始化以及开始循环,是因为Activity内部包含一个Looper对象,它会自动管理Looper,处理子线程中发送过来的消息。而初始化Handler的时候,在Handler的构造函数中,会把当前线程的Looper与Handler关联,所以在Activity中,无需显式使用Looper。