基础复习——应用Application——Application的生命周期——利用Application操作全局变量——重点
Application的生命周期
Application是Android的一大组件,在App运行过程中有且仅有一个Application对象贯穿整个生命周期。
在AndroidManifest.xml里面,activity节点的上级正是application节点。如果给application节点指定android:name属性,则表示App将运行自定义名称的Application代码。
需要注意,Application的onCreate方法调用先于Activity的onCreate方法调用。但是,Application的onTerminate方法纯属摆设,永远不会被调用。
全局的意思是其他代码都可以引用该变量,因此全局变量是共享数据和消息传递的好帮手。
适合在Application中保存的全局变量主要有下面3类数据:
(1)会频繁读取的信息,如用户名、手机号等。
(2)不方便由意图传递的数据,例如位图对象、非字符串类型的集合对象等。
(3)容易因频繁分配内存而导致内存泄漏的对象,如Handler对象等。
Java代码可利用自定义Application的静态成员变量实现全局变量的功能。具体需要完成以下3项工作:
(1)写一个继承自Application的类MainApplication。该类要采用单例模式,内部声明自身类的一个静态成员对象,然后提供该静态对象的获取方法getInstance。
(2)在Activity中调用MainApplication的getInstance方法,获得MainApplication的一个静态对象,通过该对象访问MainApplication的公共变量和公共方法。
(3)不要忘了在AndroidManifest.xml中注册新定义的Application类名,即在application节点中增加android:name属性,值为“.MainApplication”。
======================================================================================================
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.example.myapplication"> <application android:name=".MainApplication" android:allowBackup="true" android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.MyApplication" tools:targetApi="31"> <activity android:name=".AppReadActivity" android:exported="false" /> <activity android:name=".AppWriteActivity" android:exported="false" /> <activity android:name=".ImageReadActivity" android:exported="false" /> <activity android:name=".ImageWriteActivity" android:exported="false" /> <activity android:name=".FileReadActivity" android:exported="false" /> <activity android:name=".FileWriteActivity" android:exported="false" /> <activity android:name=".FilePathActivity" android:exported="false" /> <activity android:name=".LoginShareActivity" android:exported="false" /> <activity android:name=".ShareReadActivity" android:exported="false" /> <activity android:name=".ShareWriteActivity" android:exported="false" /> <activity android:name=".LoginForgetActivity" android:exported="false" /> <activity android:name=".LoginMainActivity" android:exported="false" /> <activity android:name=".EditHideActivity" android:exported="false" /> <activity android:name=".EditFocusActivity" android:exported="false" /> <activity android:name=".EditBorderActivity" android:exported="false" /> <activity android:name=".EditSimpleActivity" android:exported="false" /> <activity android:name=".TimePickerActivity" android:exported="false" /> <activity android:name=".DatePickerActivity" android:exported="false" /> <activity android:name=".AlertDialogActivity" android:exported="false" /> <activity android:name=".RadioVerticalActivity" android:exported="false" /> <activity android:name=".RadioHorizontalActivity" android:exported="false" /> <activity android:name=".SwitchIOSActivity" android:exported="false" /> <activity android:name=".SwitchDefaultActivity" android:exported="false" /> <activity android:name=".CheckBoxActivity" android:exported="false" /> <activity android:name=".DrawableStateActivity" android:exported="false" /> <activity android:name=".DrawableShapeActivity" android:exported="false" /> <activity android:name=".MetaDataActivity"> <meta-data android:name="weather" android:value="晴天" /> <!-- <meta-data --> <!-- android:name="weather" --> <!-- android:value="@string/weather_str" /> --> </activity> <activity android:name=".ReadStringActivity" android:exported="false" /> <activity android:name=".ActionUriActivity" android:exported="false" /> <activity android:name=".ActResponseActivity" android:exported="false" /> <activity android:name=".ActRequestActivity" android:exported="false" /> <activity android:name=".ActReceiveActivity" android:exported="false" /> <activity android:name=".ActSendActivity" android:exported="false" /> <activity android:name=".LoginSuccessActivity" android:exported="false" /> <activity android:name=".LoginInputActivity" android:exported="false" /> <activity android:name=".ActNextActivity" android:exported="false" /> <activity android:name=".NextActivity" android:exported="false" /> <activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <!-- 指定快捷方式。在桌面上长按应用图标,就会弹出@xml/shortcuts所描述的快捷菜单 --> <meta-data android:name="android.app.shortcuts" android:resource="@xml/shortcuts" /> </activity> </application> </manifest>
MainApplication
package com.example.myapplication; import android.app.Application; import java.util.HashMap; public class MainApplication extends Application { private static MainApplication mApp; // 声明一个当前应用的静态实例 public HashMap<String, String> infoMap = new HashMap<String, String>(); // 声明一个公共的信息映射对象,可当作全局变量使用 // 利用单例模式获取当前应用的唯一实例 public static MainApplication getInstance() { return mApp; } @Override public void onCreate() { super.onCreate(); mApp = this; } }
写布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="5dp" > <RelativeLayout android:layout_width="match_parent" android:layout_height="40dp" > <TextView android:id="@+id/tv_name" android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center" android:text="姓名:" android:textColor="@color/black" android:textSize="17sp" /> <EditText android:id="@+id/et_name" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginBottom="3dp" android:layout_marginTop="3dp" android:layout_toRightOf="@+id/tv_name" android:background="@drawable/editext_selector" android:gravity="left|center" android:hint="请输入姓名" android:inputType="text" android:maxLength="12" android:textColor="@color/black" android:textSize="17sp" /> </RelativeLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="40dp" > <TextView android:id="@+id/tv_age" android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center" android:text="年龄:" android:textColor="@color/black" android:textSize="17sp" /> <EditText android:id="@+id/et_age" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginBottom="3dp" android:layout_marginTop="3dp" android:layout_toRightOf="@+id/tv_age" android:background="@drawable/editext_selector" android:gravity="left|center" android:hint="请输入年龄" android:inputType="number" android:maxLength="2" android:textColor="@color/black" android:textSize="17sp" /> </RelativeLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="40dp" > <TextView android:id="@+id/tv_height" android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center" android:text="身高:" android:textColor="@color/black" android:textSize="17sp" /> <EditText android:id="@+id/et_height" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginBottom="3dp" android:layout_marginTop="3dp" android:layout_toRightOf="@+id/tv_height" android:background="@drawable/editext_selector" android:gravity="left|center" android:hint="请输入身高" android:inputType="number" android:maxLength="3" android:textColor="@color/black" android:textSize="17sp" /> </RelativeLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="40dp" > <TextView android:id="@+id/tv_weight" android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center" android:text="体重:" android:textColor="@color/black" android:textSize="17sp" /> <EditText android:id="@+id/et_weight" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginBottom="3dp" android:layout_marginTop="3dp" android:layout_toRightOf="@+id/tv_weight" android:background="@drawable/editext_selector" android:gravity="left|center" android:hint="请输入体重" android:inputType="numberDecimal" android:maxLength="5" android:textColor="@color/black" android:textSize="17sp" /> </RelativeLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="40dp" > <CheckBox android:id="@+id/ck_married" android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center" android:checked="false" android:text="已婚" android:textColor="@color/black" android:textSize="17sp" /> </RelativeLayout> <Button android:id="@+id/btn_save" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="保存到全局内存" android:textColor="@color/black" android:textSize="17sp" /> </LinearLayout>
代码:
package com.example.myapplication; import android.os.Bundle; import android.text.TextUtils; import android.view.View; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.EditText; import androidx.appcompat.app.AppCompatActivity; public class AppWriteActivity extends AppCompatActivity implements View.OnClickListener, CompoundButton.OnCheckedChangeListener { private EditText et_name; private EditText et_age; private EditText et_height; private EditText et_weight; private boolean isMarried = false; private String[] typeArray = {"未婚", "已婚"}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_app_write); et_name = findViewById(R.id.et_name); et_age = findViewById(R.id.et_age); et_height = findViewById(R.id.et_height); et_weight = findViewById(R.id.et_weight); CheckBox ck_married = findViewById(R.id.ck_married); ck_married.setOnCheckedChangeListener(this); findViewById(R.id.btn_save).setOnClickListener(this); } @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { isMarried = isChecked; } @Override public void onClick(View v) { if (v.getId() == R.id.btn_save) { String name = et_name.getText().toString(); String age = et_age.getText().toString(); String height = et_height.getText().toString(); String weight = et_weight.getText().toString(); if (TextUtils.isEmpty(name)) { ToastUtil.show(this, "请先填写姓名"); return; } else if (TextUtils.isEmpty(age)) { ToastUtil.show(this, "请先填写年龄"); return; } else if (TextUtils.isEmpty(height)) { ToastUtil.show(this, "请先填写身高"); return; } else if (TextUtils.isEmpty(weight)) { ToastUtil.show(this, "请先填写体重"); return; } // 获取当前应用的Application实例 MainApplication app = MainApplication.getInstance(); // 以下直接修改Application实例中保存的映射全局变量 app.infoMap.put("name", name); app.infoMap.put("age", age); app.infoMap.put("height", height); app.infoMap.put("weight", weight); app.infoMap.put("married", typeArray[!isMarried ? 0 : 1]); app.infoMap.put("update_time", DateUtil.getNowDateTime("yyyy-MM-dd HH:mm:ss")); ToastUtil.show(this, "数据已写入全局内存"); } } }
第二个布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="5dp" > <TextView android:id="@+id/tv_app" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="@color/black" android:textSize="17sp" /> </LinearLayout>
代码:
package com.example.myapplication; import android.os.Bundle; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; import java.util.Map; public class AppReadActivity extends AppCompatActivity { private TextView tv_app; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_app_read); tv_app = findViewById(R.id.tv_app); readAppMemory(); // 读取全局内存中保存的变量信息 } // 读取全局内存中保存的变量信息 private void readAppMemory() { String desc = "全局内存中保存的信息如下:"; // 获取当前应用的Application实例 MainApplication app = MainApplication.getInstance(); // 获取Application实例中保存的映射全局变量 Map<String, String> mapParam = app.infoMap; // 遍历映射全局变量内部的键值对信息 for (Map.Entry<String, String> item_map : mapParam.entrySet()) { desc = String.format("%s\n %s的取值为%s", desc, item_map.getKey(), item_map.getValue()); } if (mapParam.size() <= 0) { desc = "全局内存中保存的信息为空"; } tv_app.setText(desc); } }
ToastUtil
package com.example.myapplication; import android.content.Context; import android.widget.Toast; public class ToastUtil { public static void show(Context ctx, String desc) { Toast.makeText(ctx, desc, Toast.LENGTH_SHORT).show(); } }
DateUtil
package com.example.myapplication; import android.annotation.SuppressLint; import android.text.TextUtils; import java.text.SimpleDateFormat; import java.util.Date; @SuppressLint("SimpleDateFormat") public class DateUtil { // 获取当前的日期时间 public static String getNowDateTime(String formatStr) { String format = formatStr; if (TextUtils.isEmpty(format)) { format = "yyyyMMddHHmmss"; } SimpleDateFormat sdf = new SimpleDateFormat(format); return sdf.format(new Date()); } // 获取当前的时间 public static String getNowTime() { SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); return sdf.format(new Date()); } // 获取当前的时间(精确到毫秒) public static String getNowTimeDetail() { SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS"); return sdf.format(new Date()); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
2021-08-11 测试开发CICD——Docker——docker create ——创建一个新的容器但不启动它