Android入门(使用多媒体)
使用通知功能通知渠道:自Android8.0后引入的新概念。每个应用程序可以自由的创建当前应用应该拥有哪些通知渠道。而这些通知渠道的控制权掌握在用户手中。用户可以选择是否响铃、是否振动或者是否要关闭这个渠道的通知。对于应用而言,,通知渠道一旦创建就不可修改。所以一定要设计好有哪些渠道需要设计。
通知渠道的基本使用
首先需要一个NotificationManager对通知进行管理。可以通过调用Context的getSystemService()方法获取。这个方法接收一个参数用于确定获取系统的那个服务,如:val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager。Context.NOTIFICATION_SERVICE就是通知服务
构建通知渠道:使用NotificationChannel类构建一个通知渠道,并调用NotificationManager的createNotificationChannel()方法完成创建。由于这些类是在Android8.0后添加的,因此使用前要先判断 ...
Android入门(ContentProvider)不同应用共享数据
ContentProvider主要用于在不同的应用程序之间实现数据共享的功能
运行时权限这是ContentProvider能否使用的基础.运行时权限的意义:在旧版android中,所有的权限都是在应用安装时会直接声明出来,如果你接受这些条件就安装。否则拒绝安装就可以了。而这就会导致一些店大欺客的问题。比如:旧版微信就会申请几乎所有的权限。而你如果不接受你就不能使用微信。
所以运行时权限就有了他存在的意义:应用会在需要使用该权限时才会像用户发起申请,即便用户拒绝了,也可以正常使用其他功能。当然,并不是所有权限都需要在运行时申请,对于用户来说,不停地授权也很烦琐。Android现在将常用的权限大致归成了两类,一类是普通权限,一类是危险权限。对于普通权限,系统会帮我们自动授权。而危险权限都交给用户决定。以下是Android到Android10版本所有的危险权限:
运行时权限申请样例:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657 ...
Android使用Bee框架使用数据库
首先导入所需要的依赖项
12345678// https://mvnrepository.com/artifact/org.teasoft/bee implementation 'org.teasoft:bee:2.1.7'// https://mvnrepository.com/artifact/org.teasoft/honey implementation 'org.teasoft:honey:2.1.7'// https://mvnrepository.com/artifact/org.teasoft/bee-ext implementation 'org.teasoft:bee-ext:2.1.7' // https://mvnrepository.com/artifact/org.xerial/sqlite-jdbc implementation 'org.xerial:sqlite-jdbc:3.41.2.2'
分别是bee的三个官方库和一个sqlite驱动
...
kotlin的foreach如何实现break和continue
如何在kotin的forEach中实现break和continue?先说结论
break的实现:1234567891011fun main() { run{ (1..10).forEach { if(it%3==0) return@run println(it) } }}//结果12
这是官方推荐的方法:但是这个实现break的方法有些丑陋,凭空添加一层壳子。而网上有关于类似的做法,比如通过filter或者find预知你要判断的数,但是往往我们的break的地方不能只是在开头或者结尾用来跳过某些数,如例子而是一些特定的逻辑后,可以结束循环。
continue的实现:1234567891011121314fun main() { (1..10).forEach { if(it%3==0) return@forEach println(it) }}//结果1245781 ...
Android入门(数据持久化)
文件存储写入文件Context提供了一个openFileOutput()方法,他需要两个参数,第一个参数是文件名,不准带路径,因为所有的文件都会默认保存到/data/data/<package name>/files/下,第二个参数是操作模式,主要有MODE_PRIVATE和MODE_APPEND一个是覆写,一个是追加。openFileOutput()返回的是一个outputstream()
读取文件Context提供了一个openFileInput(),他只需要一个参数,就是文件名,它返回的是一个inputstream流。系统会自动到/data/data/<package name>/files/下寻找文件。然后你通过流的方式读取文件。
setSelection()是Edittext中,用来调节光标位置的方法。
SharedPreferences存储在SharedPreferences中,他是通过key-value的方式存储数据的。而且它存储后的内容是通过xml进行保存的。它被保存在一个固定的目录中/data/data/<packagename> ...
Android入门(广播机制)
两种广播机制:
标准广播:完全异步执行的广播,几乎所有接受者都会同时受到这个广播消息。这种广播效率高,这也意味着它不能被截断
有序广播:同步执行的广播,根据接收者优先级顺序依次发送。而且中途可以被截断。A–>B–>C;B可以在中途截断广播的传输。
接受系统广播android内置了很多系统级别的广播,比如手机开机,电量变化。这些都可以接收。
动态接收12345678910111213141516171819202122232425262728293031class MainActivity : AppCompatActivity() { //声明一个时间改变接收器,它继承自BroadcastReceiver lateinit var timeChangeReceiver: TimeChangeReceiver override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentV ...
kotlin(DSL)
领域特定语言和通用编程语言通用编程语言:有一系列足够完善的能力解决几乎所有计算机能解决的问题。领域特定语言(DSL):专注在特定任务上,放弃与之无关的功能。如SQL,正则表达式。他们趋向于解决特定的问题,但对于整个应用程序,他们是无法构造的。
DSL趋向于声明式,而通用编程语言趋向于命令式。他们的区别在于:声明式语言会将想要的结果和执行细节留给解释他的引擎。通常只需要优化一次。而命令式语言要求每一个操作都被独立优化。通常声明式会更有效率一些。而这就带来了一些缺点,比如SQL不能直接嵌入到其他语言中一起使用。单独的语言也需要单独的学习。
DSL风格的API和普通APIDSL的API往往会更加整洁而且通过DSL比单独构造出来的API更具表现力和更适宜工作。
内部DSL通过使用主要语言的特定方式,同时保留独立语法的DSL的主要优点。
DSL的结构通常DSL和API没有明确定义的边界。判断的标准往往是,DSL有着特有的结构或者说文法。一般的API相互调用直接也没有维护上下文。调用时也没有特定语法结构:这种一般被称为命令查询API。与之不同的,DSL的方式会存在一个结构。在kotlin DSL中 ...
kotlin(注解和反射)
注解使用注解使用注解只需要把@符作为名字的前缀,并放在需要注解的代码元素前面。
@Test是一个好用的注解,他可以用来测试一个方法的执行。
@Deprecated这个注解的作用是,声明那些方法已经被弃用,淘汰了。它可以与IDE一起使用。在kotlin中,他还使用了replaceWith参数加强了他。可以提供一个替代者,并且转移参数。(一条不推荐使用的消息,和一个替代者的模式)
注解能够拥有的参数基本数据类型,字符串,枚举,类引用,其他注解。他与java的不同:
要把一个类指定为注解实参,必须在类后面加上::class,表示这个类的反射。
要把另一个注解添加为实参,必须强调注解前的@。
要把一个数组指定为实参,必须使用arrayOf函数
注解使用的参数必须是已知的。也就是常数
注解目标因为一个kotlin的声明往往对应着java的多个声明。如一个属性,java中只会是一个普通的字段。而kotlin中还包括set,get方法和一些隐藏的参数。所以使用点目标可以具体确定是那个代码接受注解。Kotlin 支持的使用点目标的完整列表如下• property一 Java 的注解不能应用这种 ...
kotlin(泛型)
泛型
泛型允许你定义带类型形参的类型。
但是当这个类型的实例被创建出来时,类型形参将会被替换为类型实参的具体类型。即T,E这样的类型形参会被替换为具体的String,Int之类的。
此外,kotlin的编译器可以根据你给定的类型自动推导出所需的类型实参。但是如果你没有给定相关的类型,即编译器无法判断。如你只给定了一个空数组。此时你必须显式的说明你的类型实参是什么(就是必须写清楚<>中的参数类型)
注意,因为java中,泛型是在1.6后的版本才被引入。所以为了和老版的java兼容,他允许使用没有类型参数的泛型类型–所谓的原生态类型。而kotlin不然,他必须声明泛型的类型。
泛型类型和属性如图所示,你必须可以接受一个类型实参进入,用来代替T。
1234fun <T> testFanxing(x: T): T { println( x.hashCode()) return x as T}
他不仅可以适用与函数,也可以适用于属性
12val <T> List<T>.lastIndex:T get() ...
kotlin(内联函数)(高阶函数控制)
内联函数首先,一般情况下。lambda 表达式会被正常地编译成匿名类。这表示每调用一次lambda 表达式,一个额外的类就会被创建。并且如果 lambda 捕捉了某个变量,那么每次调用的时候都会创建一个新的对象 这会带来运行时的额外开销,导致使lambda 比使用一个直接执行相同代码的函数效率更低。
而内联函数可以解决这个效率低下的问题,也就是使用inline关键字,他在编译后,不会是一个调用函数的代码,而是直接把函数体复制并替换到当前位置,然后直接执行。
使用条件一般情况下都可以使用,但是最推荐,当你使用lambda函数时,因为这样子可以最大的提高效率。而如果你使用的lambda函数已经被定义到某个具体的类中时,或者被作为一个参数接收起来。总而言之就是必须要现场写的lambda函数。他的使用才有意义。不然他将不会被内联进来,只会编译为调用函数的过程。
JVM自动内联对于普通的函数调用,JVM己经提供了强大的内联支持。它会分析代码的执行,并在任何通过内联能够带来好处的时候将函数调用内联。这是在将宇节码转换成机器代码时自动完成的。在字节码中,每一个函数的实现只会出现一次,并不需要跟Kot ...