有了它,再也不用担心把Activity或Fragment返回数据回调到任意位置了

文章介绍了在Android开发中处理数据回调的问题,推荐使用ActivityResultAPI,它支持在非Activity和Fragment中调用,且兼容ARouter。提供了详细的API使用步骤和示例代码,简化了Activity和Fragment之间的交互。
摘要由CSDN通过智能技术生成

在Android开发中,我们时常遇到以下几个问题:

  • 当关闭当前界面时,数据回调到上一个界面,必须要在onActivityResult中处理,不能在调用的普通类中处理
  • 当使用Activity Result API时,不用在onActivityResult中处理了,但是必须要在Activity的STARTED之前初始化,很多时候自己控制不好何时初始化
  • Fragment中打开Activity,回调不走Fragment的onActivityResult(开发者使用错误造成)

其实这些,都是我们开发中很常见的,不管一个初级开发还是高级开发,都能解决这些问题,大不了面向百度编程,但是每一个人不可能都像我一样闲,把这些都总结在一起,很多道友估计都很忙,这时,我必须推荐一波,使用ActivityResultApi,而且支持ARouter回调,使用简单,通俗易懂!

API特色

  • 优雅的适配Activity Result API,真正的支持在非Activity和Fragment中调用
  • 支持不用在onResume()之前初始化ActivityResultLauncher
  • 支持ARouter
  • 支持Kotlin和Java用法
  • Kotlin扩展,使用简单

如何使用

step 1.在根目录的build.gradle添加:

allprojects {
   repositories {
      ...
      maven { url "https://jitpack.io" }
   }
} 

step 2.然后在 build.gradle(Module:XXX) 的 dependencies 添加:

dependencies {
        implementation 'com.github.ChinaLike:ActivityResultApi:最新版本号'
        //根据自己版本选择即可,最低不能低于activity-ktx:1.2.3、fragment-ktx:1.3.4
        implementation("androidx.activity:activity-ktx:1.2.3")
        implementation("androidx.fragment:fragment-ktx:1.3.4")
        //ARouter,根据自己需要引入,版本按照自己需要引入
        //implementation 'com.alibaba:arouter-api:1.5.2'
        //kapt 'com.alibaba:arouter-compiler:1.5.2'
} 

step 3.在项目自定义Application中添加或在已经有的自定义ApplicationonCreate()中添加:

class BaseApplication:Application() {

    override fun onCreate() {
        super.onCreate()
        ...
        ActivityResultApi.init(this)
        ...
    }
} 

并在AndroidManifest.xml中添加

 <application
        ...
        android:name=".BaseApplication"
        ...>
            ...
    </application> 

API介绍

registerForActivityResult(intent,activityResultCallback)

  • 普通类使用,带接收回调数据和传递数据

  • 参数说明

    • intent:类型Intent,必传
    • activityResultCallback:类型ActivityResultCallback,可选,当需要回调时传递,当不需要回调时,可不传递
  • Kotlin示例

    • 接收返回数据

      val intent = Intent(this, SecondActivity::class.java)
      intent.putExtra(Key.SOURCE, source)
      registerForActivityResult(intent) {
         //回调
      } 
      
    • 不接收返回数据

      val intent = Intent(this, SecondActivity::class.java)
      intent.putExtra(Key.SOURCE, source)
      registerForActivityResult(intent)
      //startActivity(intent) 也一样 
      
  • Java示例

    • 接收返回数据

      Intent intent = new Intent(this, SecondActivity.class);
      intent.putExtra(Key.SOURCE, source);
      ActivityResultApiExKt.registerForActivityResult(this, intent, result -> 
            //回调
      ); 
      
    • 不接收返回数据

      Intent intent = new Intent(this, SecondActivity.class);
      intent.putExtra(Key.SOURCE, source);
      ActivityResultApiExKt.registerForActivityResult(this, intent); 
      

<T:FragmentActivity> registerForActivityResult(intentExtra,activityResultCallback)

  • 普通类使用,带接收回调数据和传递数据

  • 参数说明

    • intentExtra:类型(intent: Intent) -> Unit,可选
    • activityResultCallback:类型ActivityResultCallback,可选,当需要回调时传递,当不需要回调时,可不传递
  • Kotlin示例

    • 不传递数据但接收返回数据

      registerForActivityResult<SecondActivity> {
         //回调
      } 
      
    • 传递数据同时接收返回数据

      registerForActivityResult<SecondActivity>({
         it.putExtra(Key.SOURCE, source)
      }) {
         //回调
      } 
      
    • 传递数据但不接收返回数据

      registerForActivityResult<SecondActivity>({
         it.putExtra(Key.SOURCE, source)
      }) 
      
    • 不传递数据但不接收返回数据

      registerForActivityResult<SecondActivity>(

navigation(context,navigationCallback,activityResultCallback)

  • 结合ARouter中使用,跨模块调用

  • 参数说明

    • context:类型FragmentActivity或Fragment,必传
    • navigationCallback:类型NavigationCallback,界面监听,可选
    • activityResultCallback:类型ActivityResultCallback,回调,必传
  • Kotlin示例

    • 带界面监听和接收返回数据

      ARouter.getInstance()
          .build(Router.SECOND_ACTIVITY)
          .withString(Key.SOURCE, source)
          .navigation(this, object : NavigationCallback {
      
              override fun onFound(postcard: Postcard?) {
      
              }
      
              override fun onLost(postcard: Postcard?) {
      
              }
      
              override fun onArrival(postcard: Postcard?) {
      
              }
      
              override fun onInterrupt(postcard: Postcard?) {
      
              }
      
          }) {
         //回调
          } 
      
    • 不带界面监听但接收返回数据

      ARouter.getInstance()
          .build(Router.SECOND_ACTIVITY)
          .withString(Key.SOURCE, source)
          .navigation(this) {
         //回调
          } 
      
  • Java示例

    • 带界面监听和接收返回数据

      Postcard postcard = ARouter.getInstance()
          .build(Router.SECOND_ACTIVITY)
          .withString(Key.SOURCE, source);
      ActivityResultApiExKt.navigation(postcard, this, new NavigationCallback() {
          @Override
          public void onFound(Postcard postcard) {
      
          }
      
          @Override
          public void onLost(Postcard postcard) {
      
          }
      
          @Override
          public void onArrival(Postcard postcard) {
      
          }
      
          @Override
          public void onInterrupt(Postcard postcard) {
      
          }
      }, new ActivityResultCallback<ActivityResult>() {
      
          @Override
          public void onActivityResult(ActivityResult result) {
              //回调
          }
      }); 
      

    不带界面监听但接收返回数据

    Postcard postcard = ARouter.getInstance()
            .build(Router.SECOND_ACTIVITY)
            .withString(Key.SOURCE, source);
    ActivityResultApiExKt.navigation(postcard, this, new ActivityResultCallback<ActivityResult>() {
    
        @Override
        public void onActivityResult(ActivityResult result) {
            //回调
        }
    }); 
    

最后

如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
在这里插入图片描述
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

全套视频资料:

一、面试合集
在这里插入图片描述
二、源码解析合集

在这里插入图片描述
三、开源框架合集

在这里插入图片描述
欢迎大家一键三连支持,若需要文中资料,直接扫码免费领取↓↓↓

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
package com.example.ocr; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; import androidx.appcompat.app.AppCompatActivity; import android.content.ContentValues; import android.graphics.Bitmap; import android.net.Uri; import android.os.Bundle; import android.provider.MediaStore; import android.widget.ImageView; import com.example.ocr.util.BitmapUtil; import com.example.ocr.util.DateUtil; public class MainActivity extends AppCompatActivity { private final static String TAG = "PhotoTakeActivity"; private ImageView iv_photo; private Uri mImageUri; private ActivityResultLauncher launcherThumbnail; private ActivityResultLauncher launcherOriginal; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); iv_photo = findViewById(R.id.iv_photo); launcherThumbnail = registerForActivityResult( new ActivityResultContracts.TakePicturePreview(),bitmap ->iv_photo.setImageBitmap(bitmap)); findViewById(R.id.btn_thumbnail).setOnClickListener(v -> launcherThumbnail.launch(null)); launcherOriginal = registerForActivityResult( new ActivityResultContracts.TakePicture(),result -> { if (result){ Bitmap bitmap = BitmapUtil.getAutoZoomImage(this,mImageUri); } }); findViewById(R.id.btn_original).setOnClickListener(v -> takeOriginalPhoto()); } private void takeOriginalPhoto(){ ContentValues values = new ContentValues(); values.put(MediaStore.Images.Media.DISPLAY_NAME,"photo_"+ DateUtil.getNowDateTime()); values.put(MediaStore.Images.Media.MIME_TYPE,"image/jpeg"); mImageUri = getContentResolver().insert( MediaStore.Images.Media.EXTERNAL_CONTENT_URI,values); launcherOriginal.launch(mImageUri); } }打开安卓相机闪退
06-12
根据你提供的代码,有几个可能导致应用程序崩溃的问题: 1. 没有添加相机权限。 在 AndroidManifest.xml 文件中添加以下权限: ``` <uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" /> ``` 2. 没有检查设备是否支持相机。 在启动相机之前,你应该检查设备是否支持相机。可以使用以下代码来检查: ``` private boolean isCameraAvailable() { PackageManager packageManager = getPackageManager(); return packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA); } ``` 3. 在调用 `BitmapUtil.getAutoZoomImage()` 时,可能会出现空指针异常。 在 `takeOriginalPhoto()` 方法中,你使用 `getContentResolver().insert()` 方法获取了 `mImageUri`,然后在 `launcherOriginal.launch(mImageUri)` 中传递它。但是,在 `launcherOriginal` 回调中,你实际上并没有使用 `mImageUri`,而是尝试从相机返回的结果中获取 `Bitmap`。因此,`mImageUri` 可能为空,导致 `BitmapUtil.getAutoZoomImage()` 抛出空指针异常。 你可以尝试在 `launcherOriginal` 回调中检查 `mImageUri` 是否为空,如下所示: ``` launcherOriginal = registerForActivityResult( new ActivityResultContracts.TakePicture(), result -> { if (result && mImageUri != null) { // 检查 mImageUri 是否为空 Bitmap bitmap = BitmapUtil.getAutoZoomImage(this, mImageUri); } }); ``` 这些问题可能是导致应用程序崩溃的原因。你可以尝试解决这些问题,然后再测试应用程序是否可以正常工作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值