Android四大组件全面解析,夯实基础。(中)

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: Android四大组件lay a solid foundation夯实基础

4 本地服务的启动方式

4.1 第一种

  1. 通过start方式开启服务:
  2. 使用service的步骤:


  1. 定义一个类继承 service
  2. manifest.xml文件中配置 service (当然as一键创建不用配置)
  3. 使用context的startService(Intent)方法启动服务
  4. 不使用时,调用stopService(Intent)方法停止服务


使用start方式启动的生命周期


onCreate()->onStartCommand()->onDestory();

如果服务已经开启,不会重复回调 onCreate() 方法,如果再次调用 startService()方法,service 而是会调用 onstart或者 onStartCommand()。停止服务需要调用 stopService() 方法,服务停止的时候回调 onDestory被销毁。

4.2 第二种

采用 bind 的 方式开启服务

  1. 定义一个类继承 Service
  2. 在manifest.xml 文件中注册 service
  3. 使用 context 的 bindService(Intent,ServiceConnection,int )方法启动Service
  4. 不再使用时,调用unbindService()方法停止该服务


生命周期,只会绑定一次,当多次调用绑定服务时,只会多次调用 startService()方法

Demo

public class ServiceDemo extends Service {
    private MyBinder binder=new MyBinder();
    @Override
    public void onCreate() {
        super.onCreate();
        Log.e("demo","onCreate创建");
    }
    @Override
    public boolean onUnbind(Intent intent) {
        Log.e("demo","解绑");
        return super.onUnbind(intent);
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e("demo","销毁");
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e("demo","onStartCommand服务启动");
        return super.onStartCommand(intent, flags, startId);
    }
    class MyBinder extends Binder {
        private CountDownTimer count;
        public void start(){
            count = new CountDownTimer(Integer.MAX_VALUE,1000) {
                @Override
                public void onTick(long millisUntilFinished) {
                    Toast.makeText(ServiceDemo.this, "启动啦", Toast.LENGTH_SHORT).show();
                }
                @Override
                public void onFinish() {
                }
            }.start();
        }
        public void onstop(){
            if (count != null) {
                count.cancel();
                count=null;
            }
        }
    }
    @Override
    public IBinder onBind(Intent intent) {
        Log.e("Demo","bind");
        return binder;
    }
}
public class MyServerConnection implements ServiceConnection {
    private ServiceDemo.MyBinder myBinder;
    /**
     * 第二个参数是Server中的onBind方法返回的。
     *
     * @param name
     * @param service
     */
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        Log.e("demo","开始");
        myBinder = (ServiceDemo.MyBinder) service;
        myBinder.start();
    }
    @Override
    public void onServiceDisconnected(ComponentName name) {
        myBinder.onstop();
    }
}
public class Main2Activity extends AppCompatActivity {
    MyServerConnection myServerConnection=new MyServerConnection();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        findViewById(R.id.btn_start).setOnClickListener(v -> {
            Log.e("demo","startService启动服务");
            Intent intent=new Intent(this,ServiceDemo.class);
            bindService(intent,myServerConnection,BIND_AUTO_CREATE);
        });
        findViewById(R.id.btn_stop).setOnClickListener(v -> {
            Log.e("demo","stopService服务关闭");
           unbindService(myServerConnection);
        });
    }
}

5. 远程服务

步骤1:新建定义AIDL文件,并该声明服务需要向客户端的提供的接口

步骤2:在服务子类中实现AIDL中定义的接口方法,并定义生命周期的方法(onCreat,onBind(),blabla)

步骤3:在AndroidMainfest.xml中注册服务&声明为远程服务


客户端(客户端)

步骤1:拷贝服务端的AIDL文件到目录下

步骤2:使用Stub.asInterface接口获取服务器的活页夹,根据需要调用服务提供的接口方法

步骤3:通过意图指定服务端的服务名称和所在包,绑定远程服务

6. IntentService

IntentService是Service的子类,比普通的Service增加了额外的功能。先看Service本身存在两个问题

  • Service不会专门启动一条单独的进程,Service与它所在应用位于同一个进程中;
  • Service也不是专门一条新线程,因此不应该在Service中直接处理耗时的任务;

IntentService特征:

  • 会创建独立的worker线程来处理所有的Intent请求;
  • 会创建独立的worker线程来处理onHandleIntent()方法实现的代码,无需处理多线程问题;
  • 所有请求处理完成后,IntentService会自动停止,无需调用stopSelf()方法停止Service;
  • 为Service的onBind()提供默认实现,返回null;
  • 为Service的onStartCommand提供默认实现,将请求Intent添加到队列中;

BroadcastReceiver-广播

1. 分类:

1.1 标准广播(Normal brodcasts)

标准广播是完全异步的,可以在几乎同一时刻被所有接受者接受到。因此他们之间没有任何先后顺序科研。这种广播效率比较高,但同时也意味着它是无法被截断的。

1.2 有序广播(Ordered broadcasts)

是一种同步执行的广播,在广播发出之后,同一时刻只会有一个广播接收器能够收到这条广播消息,当这个广播接收器中的逻辑执行完毕后,广播才会继续传递。所以此时的广播接收器是有先后顺序的,优先级高的广播接收器就可以先收到广播消息,并且前面的广播接收器还可以截断正在传递的广播。

1.3 本地广播 (Lolcal Brodcast) :

本地广播,即只在APP内传播,安全性高。

2 发送广播

Context.sendBroadcast()
发送的是普通广播,所有订阅者都有机会获得并进行处理。
Context.sendOrderedBroadcast()
发送的是有序广播,系统会根据接收者声明的优先级别按顺序逐个执行接收者,前面的接收者有权终止广播(BroadcastReceiver.abortBroadcast()),如果广播被前面的接收者终止,后面的接收者就再也无法获取到广播。对于有序广播,前面的接收者可以将处理结果通过setResultExtras(Bundle)方法存放进结果对象,然后传给下一个接收者,通过代码:Bundle bundle =getResultExtras(true))可以获取上一个接收者存入在结果对象中的数据。
系统收到短信,发出的广播属于有序广播。如果想阻止用户收到短信,可以通过设置优先级,让你们自定义的接收者先获取到广播,然后终止广播,这样用户就接收不到短信了。

步骤:

1,自定义一个类继承BroadcastReceiver

2,重写onReceive方法

3,在manifest.xml中注册


需要注意的是:BrodcastReceiver生命周期很短


如果需要在onReceiver 完成一些耗时操作,应该考虑在Service中开启一个新线程处理耗时操作,不应该在 BrodcastReceiver中开启一个新的线程,因为BroadcstReceiver生命周期很短,在执行完 onReceiver 以后就结束,如果开启一个新的线程,可能出现 BroadcastRecevier 退出以后线程还在,而如果 BroadcastReceiver 所在的进程结束了,该线程就会被标记为一个空线程,根据 Android 的内存管理策略,在系统内存紧张的时候,会按照优先级,结束优先级低的线程,而空线程无异是优先级最低的,这样就可能导致 BroadcastReceiver启动的子线程不能执行完成。

Demo

2.1 静态注册

public class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.e("demo", "接收到一条消息");
    }
}
public class MainActivity extends AppCompatActivity {
  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main4);
        findViewById(R.id.btn_send_Nor).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent("xxx");
                sendBroadcast(intent);
            }
        });
    }
}
//xml
<receiver
    android:name=".BroadcstReceiver.MyReceiver"
    android:enabled="true"
    android:exported="true">
    <intent-filter>
        <action android:name="xxx"/>
    </intent-filter>
</receiver>


目录
相关文章
|
2月前
|
前端开发 JavaScript
React 步骤条组件 Stepper 深入解析与常见问题
步骤条组件是构建多步骤表单或流程时的有力工具,帮助用户了解进度并导航。本文介绍了在React中实现简单步骤条的方法,包括基本结构、状态管理、样式处理及常见问题解决策略,如状态管理库的使用、自定义Hook的提取和CSS Modules的应用,以确保组件的健壮性和可维护性。
73 17
|
3月前
|
Java 开发工具 Android开发
Android与iOS开发环境搭建全解析####
本文深入探讨了Android与iOS两大移动操作系统的开发环境搭建流程,旨在为初学者及有一定基础的开发者提供详尽指南。我们将从开发工具的选择、环境配置到第一个简单应用的创建,一步步引导读者步入移动应用开发的殿堂。无论你是Android Studio的新手还是Xcode的探索者,本文都将为你扫清开发道路上的障碍,助你快速上手并享受跨平台移动开发的乐趣。 ####
|
3月前
|
搜索推荐 Android开发 开发者
探索安卓开发中的自定义视图:打造个性化UI组件
【10月更文挑战第39天】在安卓开发的世界中,自定义视图是实现独特界面设计的关键。本文将引导你理解自定义视图的概念、创建流程,以及如何通过它们增强应用的用户体验。我们将从基础出发,逐步深入,最终让你能够自信地设计和实现专属的UI组件。
|
2月前
|
存储 Linux API
深入探索Android系统架构:从内核到应用层的全面解析
本文旨在为读者提供一份详尽的Android系统架构分析,从底层的Linux内核到顶层的应用程序框架。我们将探讨Android系统的模块化设计、各层之间的交互机制以及它们如何共同协作以支持丰富多样的应用生态。通过本篇文章,开发者和爱好者可以更深入理解Android平台的工作原理,从而优化开发流程和提升应用性能。
|
2月前
|
前端开发 UED
React 文本区域组件 Textarea:深入解析与优化
本文介绍了 React 中 Textarea 组件的基础用法、常见问题及优化方法,包括状态绑定、初始值设置、样式自定义、性能优化和跨浏览器兼容性处理,并提供了代码案例。
80 8
|
2月前
|
XML 搜索推荐 前端开发
安卓开发中的自定义视图:打造个性化UI组件
在安卓应用开发中,自定义视图是一种强大的工具,它允许开发者创造独一无二的用户界面元素,从而提升应用的外观和用户体验。本文将通过一个简单的自定义视图示例,引导你了解如何在安卓项目中实现自定义组件,并探讨其背后的技术原理。我们将从基础的View类讲起,逐步深入到绘图、事件处理以及性能优化等方面。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和技巧。
|
2月前
|
Java 调度 Android开发
安卓与iOS开发中的线程管理差异解析
在移动应用开发的广阔天地中,安卓和iOS两大平台各自拥有独特的魅力。如同东西方文化的差异,它们在处理多线程任务时也展现出不同的哲学。本文将带你穿梭于这两个平台之间,比较它们在线程管理上的核心理念、实现方式及性能考量,助你成为跨平台的编程高手。
|
3月前
|
开发框架 Dart Android开发
安卓与iOS的跨平台开发:Flutter框架深度解析
在移动应用开发的海洋中,Flutter作为一艘灵活的帆船,正引领着开发者们驶向跨平台开发的新纪元。本文将揭开Flutter神秘的面纱,从其架构到核心特性,再到实际应用案例,我们将一同探索这个由谷歌打造的开源UI工具包如何让安卓与iOS应用开发变得更加高效而统一。你将看到,借助Flutter,打造精美、高性能的应用不再是难题,而是变成了一场创造性的旅程。
|
3月前
|
安全 Java Linux
深入解析Android系统架构及其对开发者的意义####
【10月更文挑战第21天】 本文旨在为读者揭开Android操作系统架构的神秘面纱,探讨其如何塑造现代移动应用开发格局。通过剖析Linux内核、硬件抽象层、运行时环境及应用程序框架等关键组件,揭示Android平台的强大功能与灵活性。文章强调了理解Android架构对于开发者优化应用性能、提升用户体验的重要性,并展望了未来技术趋势下Android的发展方向。 ####
72 0
|
3月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
122 2

热门文章

最新文章

推荐镜像

更多