首页 > 其他分享 >Android 四大控件

Android 四大控件

时间:2024-07-29 11:55:28浏览次数:8  
标签:控件 Log Service TAG 四大 Activity import Android android

一、Activity

   在 Android 应用中,Activity 是一个非常核心的组件,用于表示应用的一个单一屏幕,是用户与应用交互的主界面。每个 Activity 提供一个窗口,用于绘制界面和接收与用户的交互事件。理解 Activity 的创建、生命周期和其基本用法对于开发 Android 应用至关重要。

  一个 Android 应用通常由多个 Activity 组成,每个 Activity 都是一个独立的界面。当你打开一个应用,如邮箱应用,你看到的邮箱列表、邮件详情、写邮件等各个界面,通常都是不同的 Activity

  Activity 的生命周期是其最重要的特征之一。Android 提供了一系列的回调方法来管理 Activity 的状态,包括用户开始使用 Activity、Activity 进入前台或后台,以及 Activity 被系统销毁的时刻。

  下面是 Activity 生命周期的主要方法:

  •     onCreate(Bundle savedInstanceState): 当 Activity 被创建时调用。这是初始化界面、成员变量等的地方。
  •     onStart(): 当 Activity 对用户可见时调用。
  •     onResume(): 当 Activity 准备好与用户交互时调用,此时 Activity 位于前台。
  •     onPause(): 当系统即将启动或恢复另一个 Activity 时调用。用于保存数据或释放资源。
  •     onStop(): 当 Activity 不再对用户可见时调用。
  •     onDestroy(): 当 Activity 即将被销毁时调用。

 

 上面是关于activity 这个控件的demo代码

二、Service

  在 Android 开发中,Service 是一种用于在后台执行长时间运行的任务而不提供用户界面的应用组件。Service 可以在应用的前台或者后台执行任务,即使用户离开了应用。服务是用来处理不需要与用户交互而需要长期运行的操作,例如在后台播放音乐、执行文件下载等。

  Service 主要有两种形式:

  •     前台服务(Foreground Service):前台服务显示一个持续的通知,这意味着用户清楚地知道正在运行的服务。这种服务用于用户积极参与的任务(如播放音乐)或对用户很重要的任务(如文件下载)。
  •     后台服务(Background Service):在应用不在屏幕上显示时执行的服务。从 Android Oreo(8.0)开始,后台服务的运行受到了严格限制以优化应用对设备电池生命的影响。

  个人想法:前后台服务其实本质上没什么区别,唯一的区别就是前台会展示在页面上,但是后台不会。除此之外没有其他的区别。

 

Service 有自己的生命周期方法,用于管理其创建、启动、绑定和销毁过程:

  •     onCreate(): 服务创建时调用。
  •     onStartCommand(Intent intent, int flags, int startId): 每次通过 startService() 方法启动服务时调用。
  •     onBind(Intent intent): 当其他组件想要与服务绑定时调用,需要返回一个 IBinder 对象,通过该对象组件可以与服务进行通信。
  •     onUnbind(Intent intent): 当所有组件都与服务解除绑定时调用。
  •     onDestroy(): 服务销毁之前调用。

前台和后台本质上没有什么区别,就只写了一个后台的。

 

 

三、Broadcast Receiver

  在 Android 中,Broadcast Receiver(简称广播接收器)是一个用来处理来自系统或应用发出的广播通知的组件。它可以对诸如设备启动完成、电池电量变化、短信接收等系统事件做出响应,也可以接收应用自定义的广播消息。

 广播接收器主要用于监听和响应广播消息。广播可以是系统广播(比如网络状态改变、屏幕关闭等),也可以是应用程序发送的广播。广播接收器本身没有用户界面,但它可以启动一个活动或服务来响应接收到的信息。

广播接收器不像 Activity 或 Service 那样拥有完整的生命周期。它只有一个回调方法 onReceive(Context context, Intent intent),当接收到广播时被调用。广播接收器的类型分为两种:

  •     静态注册:在 AndroidManifest.xml 中注册。即使应用没有运行,只要事件发生,系统就会创建广播接收器的实例并调用它。
  •     动态注册:在代码中注册,通常在 Activity 或 Service 中注册。它只在其宿主组件(如 Activity)存在时活跃。

这是动态的广播

 

 这是静态的广播

 在 AndroidManifest.xml 中注册

四、Content Provider

  在 Android 中,Content Provider 是四大组件之一,用于在不同应用程序之间共享数据。它提供了一种封装数据的方式,并通过一套标准的 API 在应用之间进行数据访问。通过使用 Content Provider,一个应用可以允许其他应用访问其数据,而不需要直接访问底层数据库或文件系统。

  Content Provider 管理对一个或多个数据源(如 SQLite 数据库)的访问,通过 URI(统一资源标识符)来暴露数据。每个 URI 可以指代 Content Provider 中的数据表或表内的特定数据行。通过这种方式,Content Provider 为数据访问提供了封装,并确保了数据访问的安全性。

  核心组件

  •     URI: 每个 Content Provider 都通过一个唯一的 authority 来标识,该 authority 与 URI 结合使用,用来找到对应的 Content Provider。
  •     ContentResolver: 提供了一组 API,允许应用查询或修改由 Content Provider 管理的数据。应用通过调用 ContentResolver 的方法,如 query(), insert(), delete(), 和 update() 来执行操作。
package com.example.fourmajorcomponents;

import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

public class ContentProviderActivity extends AppCompatActivity {

    private static final String TAG = "ContentProviderActivity";
    private static final Uri CONTENT_URI = Uri.parse("content://com.example.personprovider/person");

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.content_provider_activity);

        Log.d(TAG, "Activity onCreate");

        Intent intent = new Intent(this, ContentProviderService.class);
        startService(intent);
        Log.d(TAG, "ContentProviderService started");

        Button insertButton = findViewById(R.id.insert_button);
        Button queryButton = findViewById(R.id.query_button);

        insertButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                insertData();
            }
        });

        queryButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                queryData();
            }
        });
    }

    private void insertData() {
        ContentValues values = new ContentValues();
        values.put("name", "Alice Johnson");
        values.put("age", 28);
        Uri newPersonUri = getContentResolver().insert(CONTENT_URI, values);
        if (newPersonUri != null) {
            Log.d(TAG, "Inserted new person with URI: " + newPersonUri);
            Toast.makeText(this, "Inserted new person with URI: " + newPersonUri, Toast.LENGTH_LONG).show();
        } else {
            Log.d(TAG, "Failed to insert data.");
            Toast.makeText(this, "Failed to insert data.", Toast.LENGTH_LONG).show();
        }
    }

    private void queryData() {
        Cursor cursor = getContentResolver().query(CONTENT_URI, null, null, null, null);
        if (cursor != null) {
            String[] columnNames = cursor.getColumnNames();
            Log.d(TAG, "Column names: " + String.join(", ", columnNames));

            int nameIndex = cursor.getColumnIndex("name");
            int ageIndex = cursor.getColumnIndex("age");

            if (nameIndex == -1 || ageIndex == -1) {
                Log.e(TAG, "Columns 'name' or 'age' not found in cursor.");
                Toast.makeText(this, "No data found.", Toast.LENGTH_LONG).show();
                cursor.close();
                return;
            }

            StringBuilder sb = new StringBuilder();
            while (cursor.moveToNext()) {
                String name = cursor.getString(nameIndex);
                int age = cursor.getInt(ageIndex);
                String personInfo = "Person - Name: " + name + ", Age: " + age;
                Log.d(TAG, personInfo);
                sb.append(personInfo).append("\n");
            }
            cursor.close();
            Toast.makeText(this, sb.toString(), Toast.LENGTH_LONG).show();
        } else {
            Log.d(TAG, "No data found.");
            Toast.makeText(this, "No data found.", Toast.LENGTH_LONG).show();
        }
    }
}
package com.example.fourmajorcomponents;

import android.app.Service;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

import androidx.annotation.Nullable;

public class ContentProviderService extends Service {

    private static final String TAG = "ContentProviderService";
    private SQLiteDatabase database;
    private final IBinder binder = new LocalBinder();

    public class LocalBinder extends Binder {
        ContentProviderService getService() {
            return ContentProviderService.this;
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "Service onCreate");
        DBHelper dbHelper = new DBHelper(this);
        database = dbHelper.getWritableDatabase();
        Log.d(TAG, "Database initialized");
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "Service onBind");
        return binder;
    }

    public SQLiteDatabase getDatabase() {
        return database;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (database != null && database.isOpen()) {
            database.close();
            Log.d(TAG, "Database closed");
        }
        Log.d(TAG, "Service onDestroy");
    }
}
package com.example.fourmajorcomponents;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class DBHelper extends SQLiteOpenHelper {

    private static final String TAG = "DBHelper";
    private static final String DATABASE_NAME = "people.db";
    private static final int DATABASE_VERSION = 1;

    public DBHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        Log.d(TAG, "DBHelper initialized");
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE person (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER);");
        Log.d(TAG, "Database table created");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS person");
        onCreate(db);
        Log.d(TAG, "Database upgraded");
    }
}

能实现app内资源共享

 参考网站:

  • https://zhuanlan.zhihu.com/p/529746684
  • https://blog.csdn.net/wsyx768/article/details/138511342

标签:控件,Log,Service,TAG,四大,Activity,import,Android,android
From: https://www.cnblogs.com/lachesism/p/18329806

相关文章

  • 如何在不丢失数据的情况下解锁锁定的Android手机
    你有没有发现自己处于无法访问你的Android手机的情况,因为它被锁定了?这可能是一种令人沮丧的经历,特别是如果您的设备上存储了不想丢失的重要数据。在这篇博文中,我们将探讨不同的方法,这些方法可以帮助您解锁锁定的Android手机,而不会丢失任何有价值的数据。我们了解在重新获得设备......
  • 报表控件DevExpress Reporting v24.1 - 全新升级报表查看器功能
    DevExpressReporting是.NETFramework下功能完善的报表平台,它附带了易于使用的VisualStudio报表设计器和丰富的报表控件集,包括数据透视表、图表,因此您可以构建无与伦比、信息清晰的报表。DevExpressReporting控件日前正式发布了v24.1,新版本重点针对报表查看器的一系列功能进行......
  • 通过 python 获取 android.view.ViewGroup 中的子项
    是否可以使用python、adb或任何库从android.view.ViewGroup获取子元素或文本,但不需要java和kotlin?我正在尝试使用python自动化android模拟器。与模拟器的交互通过adb进行。当我得到屏幕转储时,我看到我需要的元素是android.view.ViewGroup,并且text和content-......
  • 如何用Python制作Android服务?
    我想构建一个简单的Android应用程序,例如PushOver应用程序,它具有TCP服务器并接收其记录的文本消息,然后将其作为推送通知发送。这部分已经完成并且工作正常。但即使GUI应用程序关闭,我也想接收消息。我知道这是可能的,因为PushOver应用程序做到了!我想,我可能需要一......
  • 24.07.28 周总结 (kotlin加深 + Android studio 学习)
    Kotlin学习子类的属性覆盖AndroidstudioAI解决问题......
  • AndroidStudio 开发环境搭建
    文章目录AndroidStudio开发环境搭建JDK下载与安装,配置环境变量JDK1.8下载安装配置环境变量新建JAVA_HOME编辑Path下载AndroidStudio最新版本历史版本先安装JDK,后启动AS以管理员身份运行打开解决双击打不开的问题Error:你的主机中的软件中止了一个已建立的连接(或如下......
  • Android.mk语法规则(主要针对C编译)
    参考页面:https://www.jb51.net/program/29533325i.htmhttps://www.cnblogs.com/kn-zheng/p/17005182.htmlAndroid.mk是什么Android.mk是Android工程管理文件,类似于编译文件的说明书,用来向NDK编译系统描述源代码,并将源文件分组为模块(包括静态库、共享库、独立可执行文件)。And......
  • Qt Android 实现全屏
    本文内容参考自:https://blog.csdn.net/jun4331247/article/details/807396621.新建JFullScreen.java,添加以下代码,放置在QT安装目录\android_armv7\src\android\java\src\org\qtproject\qt5\android\bindingspackageorg.qtproject.junj;importandroid.app.Activity;import......
  • Termux Android 应用程序中 Twine 安装错误
    我想在TermuxAndroid应用程序中安装tine模块。但我发现了这个错误。截图如下。`如果您确实打算从源代码构建此软件包,请尝试从系统软件包管理器安装Rust编译器,并确保它在安装过程中位于PATH中。或者,建议使用rustup(可在https://rustup.rs......
  • GraphHopper路劲规划导航(Android源码调试运行)
    本文主要记录在运行graphhopper安卓版路径规划导航源码的步骤和遇到的问题。成功运行了程序,但是路劲规划一直不成功,问题一开始是服务地址,后来又是key的问题,在这个项目中涉及到了graphhopper、mapbox、mapilion的key,mapbox带导航的key我一直无法获取。目前最大的问题:我无法......