Android 开发必看-详解 Activity 之间的相互通信数据传递

Android 开发中,如何实现多个 Activity 相互通信?

其实上述这个问题是十分简单的,但是还是让我思考很久,也在网上查询了很多文章去了;因为我在想是把所有能想到的通信方式都列出来呢,还是只列出来重点的、常用的,良久,我还是选择了后者

开发中如若遇到多个 Activity传值问题、相邻两个之间的传值、或者多个三个以上之间的传值问题;解决方案大抵上有以下三种

1、注册或者登陆成功后 跳到某一新 Activity传值问题
2、注册界面需要选择性别 需要打开一个新的界面选择里面的信息回到当前 Activty 的传值问题
3、设置界面需要某一界面选择的图片(但是还没上传服务),如果中间相隔几种 Activty 时的传值

再来说下目前 Activity 之间的数据通信方式主要有几种:

  • Intent
  • 借助类的静态变量
  • 借助全局变量 /Application
  • 借助外部工具
    – 借助 SharedPreference
    – 使用 Android 数据库 SQLite
    – 赤裸裸的使用 File
    – Android 剪切板
  • 借助 Service

接下来我们依次来解析一下:

1) 在 Intent 跳转时携带数据

Intent 是 Android 四大组件(Activity、Service、BroadcastReceiver、ContentProvider)之间通信的纽带,在 Intent 中携带数据也是四大组件之间数据通信最常用、最普通的方式;常规写法如下:

//创建用于封装数据的Bundle对象
Bundle bundle = new Bundle();
bundle.putString("name", "WangJie");
bundle.putInt("age", 23);
 
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
//将Bundle对象嵌入Intent中
intent.putExtras(bundle);
startActivity(intent);

更简洁,也是更智能的写法是:

//创建Intent对象
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
//程序自动创建Bundle,然后将对Intent添加的数据装载在Bundle中,对用户透明
intent.putExtra("name", "WangJie");
intent.putExtra("age", 23);
startActivity(intent);

在 SecondActivity 中获取 intent 跳转时携带的数据:

//intent要用this的getIntent()获取
Intent intent = getIntent();
//用intent.getXXXExtra("key-name")或是intent.getXXXExtra("key-name", default-value)获取值
String name = intent.getStringExtra("key1");
int age = intent.getIntExtra("key2", 0);

2)借助类的静态变量来实现

由于类的静态成员可以通过 “className.fileName” 来访问,故而可以供两个 Activity 访问从而实现 Activity 之间的数据通信

在 MainActivity 中:

public class MainActivity extends AppCompatActivity {
    
    
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        //先查看一下未更改的值
        SecondActivity.age = 23;
 
        Button btn = (Button) findViewById(R.id.button);
        btn.setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                //到SecondActivity中查看对age更改是否有效
                Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                startActivity(intent);
            }
        });
    }
}

在 SecondActivity 中:

public class SecondActivity extends AppCompatActivity {
    
    
    //声明为静态file
    static int age = 0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
 
        //在MainActivity中更改了age,所以这里肯定不是"1"
        Toast.makeText(this, "在MianActivity中更改了age后的值 = " + age, Toast.LENGTH_SHORT).show();
    }
}

3)借助全局变量来实现 /Application

和类的静态变量类似,但是这个类作为单独第三个类(最好是写一个 Application 类):

public class ForExampleClass {
    
    
    //此处声明一个public static 成员来实现数据通信
    public static int age = 0;
}

在一个 Activity 中对类的静态变量进行访问和更改:

//先查看一下未更改的值
Toast.makeText(this, "age = " + ForExampleClass.age, Toast.LENGTH_SHORT).show();
//在一个Activity中对类的静态变量进行变更
ForExampleClass.age = 23;

然后在另一个 Activity 中访问该变量,来验证这种通信方式:

//先查看一下未更改的值
//在另一个Activity中访问更改后的变量来验证
Toast.makeText(this, "更改后的age = " + ForExampleClass.age, Toast.LENGTH_SHORT).show();

4)借助外部存储来实现通讯

4-1)使用 SharedPreference 实现 Activity 之间的数据通信

SharedPreference 是 Android 中最简单的文件本地化存储方式,Android API 也提供相当简单的方式来进行读写操作;下面简单看一下SharedPreference的使用:

首先,我们在 MainActivity 中先查看一下 SharedPreference 文件中的初始值,然后做更改:

public class MainActivity extends AppCompatActivity {
    
    
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        //获取Application的SharedPreference对象
        SharedPreferences sp = getApplication().getSharedPreferences("myInfo", 0);
        //get方法获取值,如果没有存储对应的key-value则返回get方法给的默认值
        String name = sp.getString("name", "null");
        int age = sp.getInt("age", 0);
        boolean isStudent = sp.getBoolean("isStudent", false);
        //查看一下初始值
        Toast.makeText(this, "MianActivity中:\n" + "name = " + name
                + "\nage = " + age + "\nisStudent = " + isStudent, Toast.LENGTH_SHORT).show();
 
        //在写入时要先获取SharedPreference的Editor对象,经过Editor进行写入
        SharedPreferences.Editor editor = sp.edit();
        editor.putString("name", "WangJie");
        editor.putInt("age", 23);
        editor.putBoolean("isStudent", true);
        //put完成后一定要commit(),否则不会生效
        editor.commit();
 
        Button btn = (Button) findViewById(R.id.button);
        btn.setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                //
                Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                startActivity(intent);
            }
        });
    }
}

然后,在 SecondActivity 中再次查看:

public class SecondActivity extends AppCompatActivity {
    
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
 
        //获取Application的SharedPreference对象
        //注意"name"值一定要一致,否则会新建一个SharedPreference对象(本地存储新增一个文件)
        SharedPreferences sp = getApplication().getSharedPreferences("myInfo", 0);
        String name = sp.getString("name", "null");
        int age = sp.getInt("age", 0);
        boolean isStudent = sp.getBoolean("isStudent", false);
 
        Toast.makeText(this, "SecondActivity中查看:\n" + "name = " + name
                + "\nage = " + age + "\nisStudent = " + isStudent, Toast.LENGTH_SHORT).show();
    }
}

5)借助Service来实现

既然存在外部太慢,那么还是在内存级别解决问题好了,这时候,你可能就需要请出 Android 四大组件之一的 Service 了;Service设计的本意,就是提供一些后台的服务,数据存取,也可以归于其职责的一部分

Service 是提供了直连机制,调用的 Activity,可以通过 bindService 方法,与目标 Service 建立一条数据通路,拿到 IBinder;这样,通过 Android 提供的 IPC 模型(进程间通信),就可以进行远程方法的调用和数据的传输了。

通过这种模式,可以解决一定问题,但是对于 Service 来说,实在是有点大材小用了,Service专长不是在数据,还是在逻辑;对于传数据而言,Service 还是重量了一点,不但是有连接耗精力,传输经由 IPC,写起来也够费劲;而且作为组件,Service 随时可能死掉,你还是要费劲心机的处理数据的持久化,得不偿失

上边分析了那么多, 看了那么一大堆的代码,我们清楚的了解到了 Activity 之间的相互通信到底有哪些;像这些关于底层的技术点,还有许多需要我们去了解学习;在这里提供一份 Android FrameWork 源码解析 思维导图及学习手册,以便大家能够更好的学习底层知识

Android FrameWork 源码解析思维导图

《应用程序与 AMS 的通讯实现》

  • 从应用程序进程到管理者进程
  • 应用程序进程向管理者进程发送消息
  • 从管理者进程到应用程序进程
  • 管理者进程向应用程序进程发送消息
  • 用户进程接收消息

《应用进程与 WMS 的通讯实现》

  • WindowManagerImpl & WindowManagerGlobal
  • ViewRootImpl
  • 从应用进程到管理者进程
  • 从管理者进程到应用进程

由于篇幅原因,仅展示部分知识点图片;上述的资料都是免费的,有需要的小伙伴:可点击此处查看直达方式 或者私信发送 “进阶” ,即可获取

好了,以上就是今天要分享的内容,大家觉得有用的话,可以点赞分享一下;如果文章中有什么问题欢迎大家指正;欢迎在评论区或后台讨论哈~

猜你喜欢

转载自blog.csdn.net/m0_70748845/article/details/127125210