Android开发基础(二)

news2024/9/28 15:32:00

Android开发基础(二)
上篇主要描述了Android系统架构,代码是通过Java表示的;
本篇将从介绍Android组件去理解Android开发,代码将对Java和Kotlin进行对比。
Android开发

Android组件

Android应用程序由一些零散的有联系的组件组成,通过一个工程manifest绑定在一起;
他们基本可以拆分为Activities(活动)、Services(服务)、Content Providers(内容提供者)、Intent(意图)、Broadcast Receiver(广播接收器)、Notification(通知),分别对应不同的作用。

一、Activities

Activity代表一个单独的屏幕,用户可以与之交互;
每个Activity都有预定义的生命周期方法,如onCreate()、onStart()、 onResume()、 onPause()、 onStop() 和 onDestroy(),这些生命周期方法在Activity的不同状态被调用;

public class MainActivity extends AppCompatActivity {  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) {  
        super.onCreate(savedInstanceState, persistentState);  
        setContentView(R.layout.activity_main);  
        // 在onCreate方法中初始化Activity  
        // 例如,可以设置布局、初始化变量等  
    }  
  
    @Override  
    protected void onStart() {  
        super.onStart();  
        // 在onStart方法中准备Activity的显示  
        // 例如,可以启动后台线程、加载数据等  
    }  
  
    @Override  
    protected void onResume() {  
        super.onResume();  
        // 在onResume方法中执行与用户交互的操作  
        // 例如,可以更新UI、处理用户输入等  
    }  
  
    @Override  
    protected void onPause() {  
        super.onPause();  
        // 在onPause方法中释放资源或保存数据  
        // 例如,可以停止后台线程、保存数据等  
    }  
  
    @Override  
    protected void onStop() {  
        super.onStop();  
        // 在onStop方法中执行清理工作  
        // 例如,可以释放资源、停止服务等  
    }  
  
    @Override  
    protected void onDestroy() {  
        super.onDestroy();  
        // 在onDestroy方法中释放Activity所占用的资源  
        // 例如,可以取消所有请求、停止所有服务等  
    }  
}
// kotlin中仅对应的继承表示变化
class MainActivity : AppCompatActivity() 

在AndroidManifest.xml文件中,可以为Activity指定不同的启动模式,这些模式定义了Activity如何被实例化和在任务堆栈中的位置;

/**
standard:这是默认的启动模式,每次启动Activity时都会创建一个新的Activity实例;
singleTop:如果Activity已经位于任务栈的顶部,系统不会创建新的Activity实例,而是复用现有的实例;
singleTask:这种模式下,系统会确保在一个任务栈中只有一个该Activity的实例;
singleInstance:与singleTask类似,但是系统为这个Activity分配一个单独的任务栈。
*/
<activity android:name=".MyActivity"  
    android:launchMode="singleTask">  
</activity>

Intent用于在应用程序的不同组件之间(如Activity)传递信息,可以使用Intent来启动一个新的Activity或向其他组件传递数据;
当用户与应用程序交互时,一系列的Activity会组成一个任务栈,用户可以后退(通过按返回键)到堆栈中的上一个Activity;
虽然Fragment不是与Activity直接相关的组件,但它们经常与Activity一起使用,Fragment代表Activity中的一个部分,可以重复使用和组织UI代码;
在AndroidManifest.xml文件中,可以为Activity指定Intent Filters,以便应用程序能够响应系统或其他应用程序发出的特定Intent;

/**
Intent.FLAG_ACTIVITY_NEW_TASK:这个标志用于创建一个新的任务栈来启动Activity;
Intent.FLAG_ACTIVITY_SINGLE_TOP:这个标志与singleTop启动模式类似;
Intent.FLAG_ACTIVITY_CLEAR_TOP:这个标志与singleTask启动模式类似;
Intent.FLAG_ACTIVITY_REORDER_TO_FRONT:这个标志将使Activity重新排序到任务栈的前面,但不会改变其启动模式。
*/
Intent intent = new Intent(this, MyActivity.class);  
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);  
startActivity(intent);
// 使用Intent.FLAG_ACTIVITY_NEW_TASK启动Activity  
        val newTaskIntent = Intent(this, OtherActivity::class.java)  
        newTaskIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK  
        startActivity(newTaskIntent)  

一个Android应用通常包含多个Activity,每个Activity负责一个特定的功能或任务;
在创建和启动Intent时,可以使用不同的Flags来控制如何启动新的Activity或处理已经存在的Activity实例;
在一个Activity结束时,可以返回一个结果给启动它的Activity,这是通过使用setResult()方法实现的。

二、Services

与Activity不同,Service不会提供用户界面,但可以在后台执行一些操作,如播放音乐、同步数据等;
在AndroidManifest.xml文件中,通过 标签定义Service;

<service android:name=".MyService" android:exported="false">  
            <intent-filter>  
                <action android:name="com.example.myapp.MyServiceAction" />  
            </intent-filter>  
        </service>  

它有一个单一的onStartCommand()方法,当Service被启动时调用,可以通过两种方式启动Service:通过Context.startService()方法或通过一个Intent;
Service也可以被其他组件绑定并与之通信,通过定义一个或多个Binder接口;

import android.app.Service  
import android.content.Intent  
import android.os.IBinder  
import android.util.Log  
  
class MyService : Service() {  
    private static final String TAG = "MyService"  
  
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {  
        Log.d(TAG, "Service started with startId: $startId")  
        // 在这里执行你的业务逻辑  
        return START_STICKY // 返回值表示如果系统需要重新创建这个 Service,它将保持其已启动的状态  
    }  
  
    override fun onBind(intent: Intent): IBinder? {  
        // 返回一个自定义的 IBinder 对象来绑定服务  
        return MyBinder()  
    }  
  
    private class MyBinder : Binder() {  
        // 提供了一个公开的方法来访问服务中的公共方法或数据  
        fun doSomething() {  
            // 在这里执行你想要的操作  
            Log.d(TAG, "Binder method called")  
        }  
    }  
}

serviceConnection = object : ServiceConnection {  
            override fun onServiceConnected(componentName: ComponentName?, b: IBinder?) {  
                // 绑定成功后,通过 IBinder 对象调用服务中的方法  
                val binder = b as MyService.MyBinder  
                myService = MyService() // 创建服务实例(如果之前没有创建)  
                binder.doSomething() // 调用服务中的方法  
            }  
  
            override fun onServiceDisconnected(componentName: ComponentName?) {  
                // 服务意外断开连接时调用此方法,可以在这里处理相关逻辑。  
            }  
        }  

val intent = Intent(this, MyService::class.java) // 创建 Intent 对象来启动服务  
    bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE) // 绑定服务并传入 Intent、ServiceConnection 和标志位(这里是自动创建)  
}

Service可以在后台执行耗时的任务,而不会阻塞用户界面;
Service可以发送和接收广播,这是Android的一种通知机制。

三、Content Providers

Content Providers是一种数据共享机制,允许应用程序将数据提供给其他应用程序使用;

public class MyProvider extends ContentProvider {
    @Override
    public boolean onCreate() {
        return false;
    }

    @Nullable
    @Override
    public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
        return null;
    }

    @Nullable
    @Override
    public String getType(@NonNull Uri uri) {
        return null;
    }

    @Nullable
    @Override
    public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
        return null;
    }

    @Override
    public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
        return 0;
    }

    @Override
    public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
        return 0;
    }
    // 实现必要的方法
}

ContentResolver resolver = getContentResolver();  
Uri uri = Uri.parse("content://com.example.myapp.myprovider/my_path");  
Cursor cursor = resolver.query(uri, projection, selection, selectionArgs, sortOrder);

四、Intent

Intent通常起着媒体中介的作用,专门提供组件互相调用的相关信息,实现调用者与被调用者之间的解耦。

五、Broadcast Receiver

用于接收来自系统或其他应用程序发送的广播,可以用于监听各种不同的事件,如系统设置更改、网络状态变化或新消息到达等。

package com.example.myapplication;  
  
import android.content.Intent;  
import androidx.core.app.JobIntentService;  
import androidx.core.content.ContextCompat;  
  
public class MyService extends JobIntentService {  
    private static final String MY_ACTION = "com.example.myapplication.MY_ACTION";  
    private static final String MY_EXTRA = "com.example.myapplication.MY_EXTRA";  
  
    public static void enqueueWork(Context context, Intent work) {  
        enqueueWork(context, MyService.class, 1, work);  
    }  
  
    @Override  
    protected void onHandleWork(Intent intent) {  
        if (intent != null && MY_ACTION.equals(intent.getAction())) {  
            String extraData = intent.getStringExtra(MY_EXTRA);  
            // 处理接收到的广播数据  
        }  
    }  
}
<service android:name=".MyService" android:exported="false">  
    <intent-filter>  
        <action android:name="com.example.myapplication.MY_ACTION"/>  
    </intent-filter>  
</service>
package com.example.myapplication;  
  
import androidx.appcompat.app.AppCompatActivity;  
import android.content.Intent;  
import android.os.Bundle;  
import androidx.core.app.JobIntentService;  
import androidx.core.content.ContextCompat;  
import androidx.core.content.IntentUtils;  
import static androidx.core.content.IntentUtilsKt.*;  
  
public class MainActivity extends AppCompatActivity {  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
  
        // 启动MyService来注册Broadcast Receiver  
        Intent work = new Intent(this, MyService.class);  
        work.setAction(MyService.MY_ACTION);  
        work.putExtra(MyService.MY_EXTRA, "额外的数据"); // 可选,根据需要传递数据给MyService处理。  
        enqueueWork(this, work); // 使用JobIntentService的enqueueWork()方法启动服务。这将在后台线程上异步执行服务。  
    }  
}

六、Notification

用于在状态栏上显示通知给用户,这些通知可以包含文本、图标、声音、振动和其他类型的视觉和听觉反馈,以向用户提供关于应用程序或其他事件的即时信息。

import android.app.NotificationChannel  
import android.app.NotificationManager  
import android.content.Context  
import android.os.Build  
import androidx.core.app.NotificationCompat  
  
public class MyNotification {  
    private Context context;  
    private NotificationManager notificationManager;  
  
    public MyNotification(Context context) {  
        this.context = context;  
        notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);  
    }  
  
    public void createNotificationChannel(String channelId, String channelName) {  
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {  
            NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT);  
            notificationManager.createNotificationChannel(channel);  
        }  
    }  
  
    public void showNotification() {  
        String channelId = "my_channel_id";  
        String channelName = "My Notification Channel";  
        createNotificationChannel(channelId, channelName);  
  
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, channelId)  
                .setContentTitle("Notification Title")  
                .setContentText("This is the notification content")  
                .setSmallIcon(R.drawable.ic_launcher);  
  
        notificationManager.notify(1, notificationBuilder.build());  
    }  
}
import android.app.NotificationChannel  
import android.app.NotificationManager  
import android.content.Context  
import android.os.Build  
import androidx.core.app.NotificationCompat  
  
class MyNotification(context: Context) {  
    private val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager  
  
    fun createNotificationChannel(channelId: String, channelName: String) {  
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {  
            val channel = NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT)  
            notificationManager.createNotificationChannel(channel)  
        }  
    }  
  
    fun showNotification() {  
        val channelId = "my_channel_id"  
        val channelName = "My Notification Channel"  
        createNotificationChannel(channelId, channelName)  
  
        val notification = NotificationCompat.Builder(context, channelId)  
            .setContentTitle("Notification Title")  
            .setContentText("This is the notification content")  
            .setSmallIcon(R.drawable.ic_launcher)  
            .build()  
  
        notificationManager.notify(1, notification)  
    }  
}

总结:Java与Kotlin

异:
Java 和 Kotlin 的语法存在显著差异,Kotlin 的语法更加简洁,减少了样板代码的数量,使得代码更加清晰易读;
Kotlin 对于空值的安全性处理比 Java 更强大,Kotlin 中的非空类型可以自动处理空值问题,减少了空指针异常的可能性;
Kotlin 支持扩展函数,可以在不修改原有类的基础上为其添加新的方法,而 Java 则不支持这一特性;
Kotlin 支持 Lambda 表达式和匿名函数,使得编写简洁、功能强大的代码更加容易,而 Java 8 之后也开始支持 Lambda 表达式,但相对 Kotlin 的语法更加繁琐;

List<String> names = Arrays.asList("Peter", "Anna", "Mike", "Xenia");  
  
Collections.sort(names, (String a, String b) -> {  
    return b.compareTo(a);  
});

new Thread(new Runnable() {  
    @Override  
    public void run() {  
        System.out.println("Hello from another thread!");  
    }  
}).start();
val names = listOf("Peter", "Anna", "Mike", "Xenia")  
names.sorted { a, b -> b.compareTo(a) } // 使用lambda表达式排序

fun main() {  
    val printMessage = { message: String -> println(message) } // 定义匿名函数  
    printMessage("Hello from Kotlin!") // 调用匿名函数  
}

Kotlin 在内存安全方面更加严格,减少了内存泄漏的风险,而 Java 需要开发者更加关注内存管理问题;
同:
两者都是静态类型语言,支持面向对象编程;
两者都可以编写 Android 应用,并且编译成字节码;
两者都支持 Android API,可以调用 Android 提供的各种组件和服务。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1379455.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

伴鱼离线数仓建设案例

伴鱼数仓建设案例 伴鱼离线数仓建立&#xff0c;与伴鱼的业务一起快速发展&#xff0c;从一条业务线&#xff0c;到多条业务线。在演进的过程中&#xff0c;有很多总结和沉淀的内容。本篇文章主要介绍伴鱼离线数据仓库的发展历史&#xff0c;在发展过程中遇到的各种问题&#…

人工智能ai写作软件哪个好,看看这6款

现如今人工智能AI写作软件逐渐成为写作者们的得力助手。这些软件利用先进的自然语言处理技术&#xff0c;能够帮助用户快速生成高质量的中文文章。在众多中文人工智能AI写作软件中&#xff0c;以下6款软件凭借其独特的优势脱颖而出&#xff0c;为用户提供了高效的写作体验。 软…

NetApp E系列(E-Series)OEM产品介绍以及如何收集日志和保存配置信息

NetApp E系列是NetApp收购LSI存储后建立的一条新的产品线&#xff0c;由于LSI存储的历史悠久&#xff0c;所以这条产品线给NetApp带来了很多的OEM产品&#xff0c;可以说E系列是世界上OEM给最多公司的存储产品线也不为过&#xff0c;因为最早LSI的产品销售测率就是OEM&#xff…

Java 面试题 - 多线程并发篇

线程基础 创建线程有几种方式 继承Thread类 可以创建一个继承自Thread类的子类&#xff0c;并重写其run()方法来定义线程的行为。然后可以通过创建该子类的实例来启动线程。 示例代码&#xff1a; class MyThread extends Thread {public void run() {// 定义线程的行为} …

【C语言】指针知识点笔记(1)

以下的思维导图是胖达学习指针时记得笔记&#xff0c;是根据自己的习惯所记录的&#xff0c;希望能对大家的学习有所帮助&#xff0c;如果大家喜欢的话我后面会陆续更新其他章节的笔记&#xff0c;喜欢的话就评论一下吧&#xff01; 目录 一、内存和地址 二、指针和变量地址…

P122 神经网络压缩Network compression-purning

在 边缘设备上跑时,模型太大,跑不动 、purn: 删减 删减以后,正确率有影响会下降 为解决这个问题,进行微调,每次只减一点参数,重复多次。 使得最后修剪后的模型跟原来的模型差别不大。 判断某一个参数是否重要,是否要去掉 问题:进行过修剪后不规则的网络,pytorch难以…

【惠友骨科小课堂】拇外翻常见的几个误区,来看看你中了几个?

拇外翻作为常见的足部畸形&#xff0c;在日常生活中困扰着许多人。歪脚趾不仅外观不好看&#xff0c;还会出现疼痛、影响行走运动。但大多数人对于拇外翻的认识都不足常常落入认知误区&#xff0c;快来看看你中了几个&#xff1f; 误区一Q 我都没穿过高跟鞋&#xff0c;怎么也…

【工业物联网】现代企业环境中的DCS(分布式控制系统)和SCADA(站点控制和数据采集)...

快答案&#xff1a; SCADA和DCS作为单独的系统开始&#xff0c;但一起成长。今天的带宽如此广泛&#xff0c;不需要在每个节点进行本地化。 SCADA和DCS&#xff1a;如果您参与管理企业级网络&#xff0c;您可能已经听说过这些术语。本文将阐明两种技术之间的区别。请注意&#…

【ACL 2023】 The Art of Prompting Event Detection based on Type Specific Prompts

【ACL 2023】 The Art of Prompting: Event Detection based on Type Specific Prompts 论文&#xff1a;https://aclanthology.org/2023.acl-short.111/ 代码&#xff1a;https://github.com/VT-NLP/Event_APEX Abstract 我们比较了各种形式的提示来表示事件类型&#xff0…

python 语法

闭包 在函数嵌套的前提下&#xff0c;内部函数使用了外部函数的变量&#xff0c;并且外部函数返回了内部函数&#xff0c;我们把这个使用外部函数变量的内部函数称为闭包。 def outfunc(arg):def innerFunc(msg):print(f"<{msg}> {arg} <{msg}>")retu…

C1-3.2 关于‘神经网络’

C1-3.2 关于‘神经网络’ 【注释】 彩色图像&#xff08;RGB&#xff09;由三原色构成&#xff0c;二维图像在任意一个点像素为立体三层结构&#xff0c;分别是红色、绿色、蓝色值&#xff0c;该值的范围在0∽255之间 1、全连接神经网络——整体架构 【注释】&#xff1a; …

【目标检测】评价指标:混淆矩阵概念及其计算方法(yolo源码)

本篇文章首先介绍目标检测任务中的评价指标混淆矩阵的概念&#xff0c;然后介绍其在yolo源码中的实现方法。 目标检测中的评价指标&#xff1a; mAP概念及其计算方法(yolo源码/pycocotools) 混淆矩阵概念及其计算方法(yolo源码) 本文目录 1 概念2 计算方法 1 概念 在分类任务中…

《安富莱嵌入式周报》第330期:开源ECU模组,开源USB PD供电SMD回流焊,嵌入式系统开发C代码参考指南,旨在提升C语言编写的源码质量

周报汇总地址&#xff1a;嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 更新一期视频教程 BSP视频教程第29期&#xff1a;J1939协议栈CAN总线专题&#xff0c;源码框架&#xff0c;执行流程和…

从零学Java Map集合

Java Map集合 文章目录 Java Map集合1 Map 结构2 Map 父接口2.1 Map接口的特点2.2 常用方法 3 Map集合的实现类3.1 HashMap【重点】3.2 LinkedHashMap3.3 TreeMap3.4 Hashtable&#xff08;了解&#xff09;3.5 Properties 属性集合 4 HashMap 源码分析 1 Map 结构 概念: 将键…

react输入框检索树形(tree)结构

input搜索框搜索树形子级内容1. input框输入搜索内容2. 获取tree结构数据3. 与tree匹配输入的内容&#xff0c;tree是多维数组&#xff0c;一级一级的对比输入的内容是否匹配&#xff0c;用forEach循环遍历数据&#xff0c;匹配不到在往下找&#xff0c;直到找到为null &#x…

2024年甘肃省职业院校技能大赛信息安全管理与评估 样题二 模块二

竞赛需要完成三个阶段的任务&#xff0c;分别完成三个模块&#xff0c;总分共计 1000分。三个模块内容和分值分别是&#xff1a; 1.第一阶段&#xff1a;模块一 网络平台搭建与设备安全防护&#xff08;180 分钟&#xff0c;300 分&#xff09;。 2.第二阶段&#xff1a;模块二…

数据结构排序——详细讲解归并排序(c语言实现递归及非递归)

上次是快排和冒泡&#xff1a;数据结构排序——详解快排及其优化和冒泡排序(c语言实现、附有图片与动图示意&#xff09; 今天为大家带来归并排序 文章目录 1.基本思想2.递归实现3.非递归实现 1.基本思想 归并排序是一种分治算法&#xff0c;它将序列分成两个子序列&#xff0…

Docker与微服务实战(高级篇)- 【上】

Docker与微服务实战&#xff08;高级篇&#xff09;- 【上】 一、Docker复杂安装详说1.1 Mysql主从复制--原理-【尚硅谷Mysql高级篇】1.2 Mysql主从复制--【一主一从】搭建步骤1.2.1新建--【主服务器】--容器实例--33071.2.2.进入/app/mysql-master/conf目录下新建my.cnf1.2.3.…

3d建模软件有哪些?3d云渲染推荐

3D建模软件有很多&#xff0c;有的非常复杂难以上手&#xff0c;那么适合新手的有哪些呢&#xff1f;一起来看看吧。 1、SketchUp SketchUp是一个用户友好且直观的建模软件&#xff0c;能与V-Ray渲染器一起使用&#xff0c;适合初学者。2、Blender Blender是一个功能强大且免费…

超声波清洗机可以洗些什么东西?质量比较好的超声波清洗机推荐

超声波清洗机只能清洗眼镜吗&#xff1f;不是的&#xff01;超声波清洗机能够清洗的物品远比我们想象的还多&#xff0c;最常见的还是清洗眼镜&#xff0c;毕竟超声波清洗机最常见就是在眼镜店了&#xff0c;很多朋友都喜欢定期都眼镜店里来清洗一下眼镜&#xff0c;这个习惯其…