• 【Android】-- 数据存储(二)(存储卡上读写文件、Application保存数据)


    目录

    一、在存储卡上读写图片文件

    二、Application

    1、Application生命周期

    2、利用Application操作全局变量


    一、在存储卡上读写图片文件

    Android的位图工具是Bitmap,App读写Bitmap可以使用性能更好的BufferedOutputStream和BufferedInputStream。

    Android还提供了BitmapFactory工具用于读取各种来源的图片,相关方法如下:

    • decodeResource:该方法可从资源文件中读取图片信息。
    • decodeFile:该方法可将指定路径的图片读取到Bitmap对象。
    • decodeStream:该方法从输入流中读取位图数据。

    例:点击保存再点击读取后出现图片

     XML文件

    1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    2. android:layout_width="match_parent"
    3. android:layout_height="match_parent"
    4. android:orientation="vertical">
    5. <Button
    6. android:id="@+id/btn_save"
    7. android:layout_width="match_parent"
    8. android:layout_height="wrap_content"
    9. android:text="保存"/>
    10. <Button
    11. android:id="@+id/btn_read"
    12. android:layout_width="match_parent"
    13. android:layout_height="wrap_content"
    14. android:text="读取"/>
    15. <ImageView
    16. android:id="@+id/iv_content"
    17. android:layout_width="match_parent"
    18. android:layout_height="400dp"
    19. android:scaleType="fitCenter"/>
    20. </LinearLayout>

     java代码

    1. public class ImageWriteActivity extends AppCompatActivity implements View.OnClickListener {
    2. private ImageView iv_content;
    3. private String path;
    4. @Override
    5. protected void onCreate(Bundle savedInstanceState) {
    6. super.onCreate(savedInstanceState);
    7. setContentView(R.layout.activity_image_write);
    8. iv_content = findViewById(R.id.iv_content);
    9. findViewById(R.id.btn_save).setOnClickListener(this);
    10. findViewById(R.id.btn_read).setOnClickListener(this);
    11. }
    12. @Override
    13. public void onClick(View view) {
    14. switch (view.getId()){
    15. case R.id.btn_save:
    16. String fileName = System.currentTimeMillis()+".jpeg";
    17. // 获取当前APP的私有下载目录
    18. path = getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString()+ File.separatorChar+fileName;
    19. // 从指定的资源文件中获取位图对象
    20. Bitmap b1 = BitmapFactory.decodeResource(getResources(),R.drawable.thing1);
    21. // 把位图对象保存为图片文件
    22. FileUtil.saveImage(path,b1);
    23. Toast.makeText(this,"保存成功",Toast.LENGTH_SHORT).show();
    24. break;
    25. case R.id.btn_read:
    26. Bitmap b2 = FileUtil.openImage(path);
    27. iv_content.setImageBitmap(b2);
    28. break;
    29. }
    30. }
    31. }

    FileUtil类

    1. public class FileUtil {
    2. // 把位图数据保存到指定路径的图片文件
    3. public static void saveImage(String path, Bitmap bitmap) {
    4. FileOutputStream fos = null;
    5. try {
    6. fos = new FileOutputStream(path);
    7. // 把文件数据压缩到文件输出流
    8. bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
    9. } catch (Exception e) {
    10. e.printStackTrace();
    11. } finally {
    12. if (fos != null) {
    13. try {
    14. fos.close();
    15. } catch (IOException e) {
    16. e.printStackTrace();
    17. }
    18. }
    19. }
    20. }
    21. //从指定路径的图片文件中读取位图数据
    22. public static Bitmap openImage(String path) {
    23. Bitmap bitmap = null;
    24. FileInputStream fis = null;
    25. try {
    26. fis = new FileInputStream(path);
    27. bitmap = BitmapFactory.decodeStream(fis);
    28. } catch (Exception e) {
    29. e.printStackTrace();
    30. } finally {
    31. if (fis != null) {
    32. try {
    33. fis.close();
    34. } catch (IOException e) {
    35. e.printStackTrace();
    36. }
    37. }
    38. }
    39. return bitmap;
    40. }
    41. }

    二、Application

    1、Application生命周期

    Application是Android的一大组件,在App运行过程中有且仅有一个Application对象贯穿整个生命周期。

    清单文件AndroidMainifest.xml文件中有个application标签,没有指定则使用默认;

    可以新建一个MyApplication类继承Application,然后在清单文件中加入以下代码指定使用自定义的application。

            android:name=".MyApplication"

    MyApplication类

    1. public class MyApplication extends Application {
    2. //App启动时调用
    3. public void onCreate() {
    4. super.onCreate();
    5. mApp = this;
    6. }
    7. //App终止调用
    8. @Override
    9. public void onTerminate() {
    10. super.onTerminate();
    11. }
    12. //App配置改变调用,如竖屏变为横屏
    13. @Override
    14. public void onConfigurationChanged(@NonNull Configuration newConfig) {
    15. super.onConfigurationChanged(newConfig);
    16. }
    17. }

    2、利用Application操作全局变量

    全局的意思是其他代码都可以引用该变量,因此全局变量是共享数据和消息传递的好方法。

    适合在Application中保存的全局变量主要有:

    • 会频繁读取的信息,如用户名、手机号等。
    • 不方便由意图传递的数据,如位图对象、非字符串类型的集合对象等。
    • 容易因频繁分配内容而导致内存泄漏的对象,如Handler对象等。

    例:输入信息点击保存,只要应用不挂掉,重新回到应用还会有输入的信息。

     XML文件

    1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    2. android:layout_width="match_parent"
    3. android:layout_height="match_parent"
    4. android:orientation="vertical"
    5. android:padding="5dp">
    6. <LinearLayout
    7. android:layout_width="match_parent"
    8. android:layout_height="40dp"
    9. android:orientation="horizontal">
    10. <TextView
    11. android:id="@+id/tv_name"
    12. android:layout_width="wrap_content"
    13. android:layout_height="match_parent"
    14. android:gravity="center"
    15. android:text="姓名"
    16. android:textSize="17sp"/>
    17. <EditText
    18. android:id="@+id/et_name"
    19. android:layout_width="0dp"
    20. android:layout_height="match_parent"
    21. android:layout_weight="1"
    22. android:hint="请输入姓名"
    23. android:inputType="text"
    24. android:textSize="17sp"/>
    25. </LinearLayout>
    26. <Button
    27. android:id="@+id/btn_save"
    28. android:layout_width="match_parent"
    29. android:layout_height="wrap_content"
    30. android:text="保存"
    31. android:textSize="17sp"/>
    32. </LinearLayout>

    java类

    1. public class AppWriteActivity extends AppCompatActivity implements View.OnClickListener {
    2. private EditText et_name;
    3. private MyApplication app;
    4. @Override
    5. protected void onCreate(Bundle savedInstanceState) {
    6. super.onCreate(savedInstanceState);
    7. setContentView(R.layout.activity_app_write);
    8. et_name = findViewById(R.id.et_name);
    9. app = MyApplication.getInstance();
    10. findViewById(R.id.btn_save).setOnClickListener(this);
    11. reload();
    12. }
    13. private void reload() {
    14. String name = app.infoMap.get("name");
    15. if(name == null)
    16. return;
    17. et_name.setText(name);
    18. }
    19. @Override
    20. public void onClick(View view) {
    21. String name = et_name.getText().toString();
    22. app.infoMap.put("name",name);
    23. }
    24. }

    MyApplication类

    1. public class MyApplication extends Application {
    2. private static MyApplication mApp;
    3. // 声明一个公共的信息映射对象,可当作全局变量使用
    4. public HashMap<String,String> infoMap = new HashMap<>();
    5. public static MyApplication getInstance(){
    6. return mApp;
    7. }
    8. //App启动时调用
    9. public void onCreate() {
    10. super.onCreate();
    11. mApp = this;
    12. }
    13. //App终止调用
    14. @Override
    15. public void onTerminate() {
    16. super.onTerminate();
    17. }
    18. //App配置改变调用,如竖屏变为横屏
    19. @Override
    20. public void onConfigurationChanged(@NonNull Configuration newConfig) {
    21. super.onConfigurationChanged(newConfig);
    22. }
    23. }

  • 相关阅读:
    RabbitMQ死信队列与延迟队列
    【设计模式】【单例模式】python实现单例模式的几种方式
    Python---练习:while循环嵌套(用两次while三步走--里外各一次)
    这些mysql基础命令、基础知识还记得吗?(面试,学习,复习都可以)一万三千字总结
    Spring异步任务async介绍与案例实战
    快速幂算法
    mysql增加分区
    单片机卡死的几大原因、分析、解决
    这七个Github仓库,够学一辈子!
    STM32H563烧录后无法擦除
  • 原文地址:https://blog.csdn.net/Tir_zhang/article/details/127041057