Android接入AWS SDK,想实现运行时动态切换AWS的用户账号及运行时环境,遇到问题记录

总结

作为一名从事Android的开发者,很多人最近都在和我吐槽Android是不是快要凉了?而在我看来这正是市场成熟的表现,所有的市场都是温水煮青蛙,永远会淘汰掉不愿意学习改变,安于现状的那批人,希望所有的人能在大浪淘沙中留下来,因为对于市场的逐渐成熟,平凡并不是我们唯一的答案!

资料.png
资料图.jpg

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

            .devMenuEnabled(false)

            .build()



        Amplify.configure(config, application)

    } catch (e: AmplifyException) {

        e.printStackTrace()

    }



初始化配置`Amplify.configure(config, application)` 进入方法内部,如下截图  

![在这里插入图片描述](https://img-blog.csdnimg.cn/20210113085611750.jpeg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FuZHJvaWRfbHM=,size_16,color_FFFFFF,t_70#pic_center)



发现它内部有一个配置同步锁,在Amplify类中的定义如下



private static final AtomicBoolean CONFIGURATION_LOCK = new AtomicBoolean(false);




一旦初始化后,若再次初始化,则抛出如下异常



throw new AmplifyException(

“The client issued a subsequent call to Amplify.configure after the first had already succeeded.”, “Be sure to only call Amplify.configure once”

);




`CONFIGURATION_LOCK`是私有的静态常量,也就是说我们改不了



2、使用Java的反射技术(代码是使用的Kotlin语言),去尝试修改,代码如下:



val amplifyClass: Class<*> = Amplify::class.java

val configurationLock = amplifyClass.getDeclaredField(“CONFIGURATION_LOCK”)

configurationLock.isAccessible = true

configurationLock.set(null, AtomicBoolean(false))




编译运行,发现还是不行,遇到了如下异常(是UserAgent类的)



throw new AmplifyException(

   "User-Agent was already configured successfully.",

   "User-Agent is configured internally during Amplify configuration. " +

    "This method should not be called externally."

);




通过翻阅源码,发现UserAgent类有提供重置方法



UserAgent.reset()




我们再次编译运行,发现还是不行,遇到了如下异常(是Category类的)



if (!State.NOT_CONFIGURED.equals(state.get())) {

      throw new AmplifyException(

                "Category " + getCategoryType() + " has already been configured or is currently configuring.", "Ensure that you are only attempting configuration once."

            );

}




翻阅Category类的源码,看到了如下代码



/**

 * Records the initialization state. See {@link State} for possible values.

 */

private final AtomicReference<State> state;



/**

 * Constructs a new, not-yet-configured, Category.

 */

public Category() {

    this.plugins = new ConcurrentHashMap<>();

    this.state = new AtomicReference<>(State.NOT_CONFIGURED);

}



也就是state变量的值,我们通过常规的手段修改不了,我们继续使用反射技术,代码如下:



try {

        val categoryClass = Class.forName("com.amplifyframework.core.category.Category\$State")

        val notConfiguredField = categoryClass.getField("NOT_CONFIGURED")

        notConfiguredField.isAccessible = true

        val notConfigured = notConfiguredField.get(null)



        val authCategoryState = Class.forName("com.amplifyframework.auth.AuthCategory").superclass.getDeclaredField("state")

        authCategoryState.isAccessible = true

        authCategoryState.set(Amplify.Auth, AtomicReference(notConfigured))



        val analyticsState = Class.forName("com.amplifyframework.analytics.AnalyticsCategory").superclass.getDeclaredField("state")

        analyticsState.isAccessible = true

        analyticsState.set(Amplify.Analytics, AtomicReference(notConfigured))



        val apiState = Class.forName("com.amplifyframework.api.ApiCategory").superclass.getDeclaredField("state")

        apiState.isAccessible = true

        apiState.set(Amplify.API, AtomicReference(notConfigured))



        val loggingState = Class.forName("com.amplifyframework.logging.LoggingCategory").superclass.getDeclaredField("state")

        loggingState.isAccessible = true

        loggingState.set(Amplify.Logging, AtomicReference(notConfigured))



        val storageState = Class.forName("com.amplifyframework.storage.StorageCategory").superclass.getDeclaredField("state")

        storageState.isAccessible = true

        storageState.set(Amplify.Storage, AtomicReference(notConfigured))



        val hubState = Class.forName("com.amplifyframework.hub.HubCategory").superclass.getDeclaredField("state")

        hubState.isAccessible = true

        hubState.set(Amplify.Hub, AtomicReference(notConfigured))



        val dataStoreState = Class.forName("com.amplifyframework.datastore.DataStoreCategory").superclass.getDeclaredField("state")

        dataStoreState.isAccessible = true

        dataStoreState.set(Amplify.DataStore, AtomicReference(notConfigured))



        val predictionsState = Class.forName("com.amplifyframework.predictions.PredictionsCategory").superclass.getDeclaredField("state")

        predictionsState.isAccessible = true

        predictionsState.set(Amplify.Predictions, AtomicReference(notConfigured))



        val categoriesMap = buildCategoriesMap()

        val categories = amplifyClass.getDeclaredField("CATEGORIES")

        categories.isAccessible = true

        categories.set(null, categoriesMap)

        

        val initializationPool = amplifyClass.getDeclaredField("INITIALIZATION_POOL")

        initializationPool.isAccessible = true

        initializationPool.set(null, Executors.newFixedThreadPool(categoriesMap.size))

    } catch (e: Exception) {

        e.printStackTrace()

    }



编译、运行,这次发现终于不再包异常了,那问题解决了吗?实现了我们在运行时,动态切换AWS账号及环境的目的了没?**答案是:没有!。** 你没看错,现在呢是编译、运行一切正常,但是就是没实现运行时动态切AWS账号及环境。



##### []( )关于重置AWS SDK 初始化相关限制的完整代码如下:



package com.majiapp.app

import android.annotation.SuppressLint

import android.app.Application

import com.amplifyframework.AmplifyException

import com.amplifyframework.core.Amplify

import com.amplifyframework.core.AmplifyConfiguration

import com.amplifyframework.core.category.Category

import com.amplifyframework.core.category.CategoryType

import com.amplifyframework.core.plugin.Plugin

import com.amplifyframework.util.UserAgent

import com.majiapp.R

import com.majiapp.buildconfig.BuildEnvConfig

import com.majiapp.tu.TuApplication

import java.util.*

import java.util.concurrent.Executors

import java.util.concurrent.atomic.AtomicBoolean

import java.util.concurrent.atomic.AtomicReference

object AppEvnInit {

fun init(appContext: TuApplication) {

    resetCategoriesState()

    initAmplify(appContext)

}



private fun initAmplify(application: Application) {

    try {

        val amplifyConfig = if (BuildEnvConfig.isProdEnv()) {

            R.raw.amplifyconfiguration_prod

        } else {

            R.raw.amplifyconfiguration

总结

算法知识点繁多,企业考察的题目千变万化,面对越来越近的“金九银十”,我给大家准备好了一套比较完善的学习方法,希望能帮助大家在有限的时间里尽可能系统快速的恶补算法,通过高效的学习来提高大家面试中算法模块的通过率。

这一套学习资料既有文字档也有视频,里面不仅仅有关键知识点的整理,还有案例的算法相关部分的讲解,可以帮助大家更好更全面的进行学习,二者搭配起来学习效果会更好。

部分资料展示:




有了这套学习资料,坚持刷题一周,你就会发现自己的算法知识体系有明显的完善,离大厂Offer的距离更加近。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

15173000038)]
[外链图片转存中…(img-1FPnTSbg-1715173000038)]
[外链图片转存中…(img-MQLGljoe-1715173000039)]

有了这套学习资料,坚持刷题一周,你就会发现自己的算法知识体系有明显的完善,离大厂Offer的距离更加近。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 14
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
连接 AWS IoT Core 需要使用 AWS IoT C++ SDK。具体步骤如下: 1. 安装 AWS IoT C++ SDK 可以使用以下命令在 Linux 上安装 AWS IoT C++ SDK: ``` sudo apt-get update sudo apt-get install libaws-cpp-sdk-iot ``` 2. 创建 AWS IoT Core 的证书和密钥 在 AWS IoT 控制台上创建一个设备,并为该设备创建一个证书和密钥。请记住这些凭据,它们将用于连接到 AWS IoT Core。 3. 编写代码连接 AWS IoT Core 以下是连接 AWS IoT Core 的示例代码: ``` #include <aws/iot-data/iot-data-client.h> // AWS IoT C++ SDK 头文件 #include <cstdlib> #include <cstring> #include <iostream> using namespace Aws::IoTData; int main(int argc, char** argv) { Aws::SDKOptions options; Aws::InitAPI(options); // AWS IoT Core 的端点 const char* endpoint = "xxxxxxxxxxxxxx-ats.iot.us-west-2.amazonaws.com"; // 设备的证书和密钥 const char* certPath = "/path/to/certificate.pem.crt"; const char* keyPath = "/path/to/private.pem.key"; // 创建 IoT 数据客户端对象 IoTDataClient iotDataClient(endpoint, certPath, keyPath); // 发布消息到主题 const char* topic = "my/topic"; const char* message = "Hello, AWS IoT Core!"; PublishRequest publishRequest; publishRequest.SetTopic(topic); publishRequest.SetPayload((unsigned char*)message, strlen(message)); iotDataClient.Publish(publishRequest); Aws::ShutdownAPI(options); return 0; } ``` 在上面的代码中,我们创建了一个 IoT 数据客户端对象,并使用其 `Publish` 方法发布消息到主题。连接 AWS IoT Core 的参数包括端点、证书和密钥等,需要根据自己的实际情况进行设置。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值