项目运行中的新发现

项目: TFTD

今天在Nook Tablet上面测试背景音乐的问题,往复N次发现,app 会crash. 报出的exception是: 数据越界,

06-01 00:48:53.037: E/AndroidRuntime(6180): Caused by: java.lang.IndexOutOfBoundsException: Invalid index 1, size is 0

06-01 00:48:53.037: E/AndroidRuntime(6180): at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:257)

06-01 00:48:53.037: E/AndroidRuntime(6180): at java.util.ArrayList.get(ArrayList.java:311)

06-01 00:48:53.037: E/AndroidRuntime(6180): at com.xxx.application.TFTDApplication.setBooleanFavorite(TFTDApplication.java:489)

06-01 00:48:53.037: E/AndroidRuntime(6180): at com.xxx.activity.ThoughtsActivity.onResume(ThoughtsActivity.java:364)

06-01 00:48:53.037: E/AndroidRuntime(6180): at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1150)

06-01 00:48:53.037: E/AndroidRuntime(6180): at android.app.Activity.performResume(Activity.java:3839)

06-01 00:48:53.037: E/AndroidRuntime(6180): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2110)

06-01 00:48:53.037: E/AndroidRuntime(6180): ... 19 more



究其原因是在后一个activity的onResume()方法中与前一个activity异步的加载数据的代码块共用了一个数据集合对象,导致数据越界,这个问题找了好久好久,都没有发现,

现在终于明白了,一直想不明白为什么,明明打印出来是size == 3, 为什么用for循环取的时候还是会越界。


终于发现了,为什么会前面一个activity会再次运行呢?明明已经创建过了,为什么还会再次onCreate()?不明白,为什么这个问题在Nook Tablet上出现了,在手机端不易出现。


找了好久,终于发现:这跟你用什么方式来打开app有关系。


在手机上,我一般都是从桌面直接点击打来,或者直接在app里直接打开。


这次在Nook Tablet上面我其实是通过文件浏览器打开的,我使用了Search功能,找到后直接点击。我发现这个点击操作其实是重新发出了一个intent,导致这个activity会重新创建运行,而并不管这个app是否已经运行了,activity是否已经存在实例了。对于那些在处在后台的app也重新创新一个新的activity打开。

我又在手机端,使用search功能找到我的app,点击,发现我的app中的activity也会重新onCreate()。


因此activity重新onCreate()一下。


测试方法:

      1. 看看TFTDApplication 的onCreate()方法是不是重新执行了 ===》 false

      2. 看看MyTabActivity 的onCreate()方法是不是重新执行了 ===》 true

      3. 看看ThoughtsActivity 的onCreate()方法是不是重新执行了 ===》 true


当然这个也跟你的Activity创建方式的设置有关系!!!





项目运行过程中动态修改 Redis 的连接地址,通常不建议直接修改配置文件并重启服务,因为这会导致连接中断。为了实现不停机更新 Redis 地址,可以采用以下几种方式: 1. **使用连接池的动态更新机制**: 如果项目中使用了像 Lettuce 或 Jedis 这类支持连接池的客户端库,可以在运行时动态关闭旧连接并建立新的连接。例如,在 Spring Boot 项目中,可以通过重新配置 `RedisConnectionFactory` 来实现这一点。具体做法是创建一个新的 `RedisStandaloneConfiguration` 实例并设置新的主机和端口,然后将其注入到 `LettuceConnectionFactory` 中,并刷新连接池[^2]。 ```java RedisStandaloneConfiguration config = new RedisStandaloneConfiguration("new_host", 6379); LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(config); connectionFactory.afterPropertiesSet(); // 初始化新连接 redisTemplate.setConnectionFactory(connectionFactory); // 更新 RedisTemplate 的连接工厂 ``` 2. **通过服务发现机制实现动态配置**: 在微服务架构中,可以借助服务注册与发现机制(如 Eureka、Consul 或 Nacos)来管理 Redis 的地址信息。服务可以从注册中心动态获取 Redis 的连接信息,并在运行时监听配置变更事件,从而实现无缝切换。这种方式适合大规模分布式系统,能够提升系统的弹性和可维护性[^1]。 3. **利用配置中心实现运行时配置更新**: 使用如 Spring Cloud Config、Alibaba Nacos Config 等配置中心工具,可以在不重启应用的前提下更新配置。通过监听配置变更事件,应用可以在运行时动态更新 Redis 的连接地址。例如,结合 `@RefreshScope` 注解和 Spring Cloud Bus,可以实现配置的热更新[^3]。 ```java @Component @RefreshScope public class RedisConfig { @Value("${redis.host}") private String host; // 获取新的 Redis 连接 public RedisConnectionFactory getRedisConnectionFactory() { RedisStandaloneConfiguration config = new RedisStandaloneConfiguration(host, 6379); return new LettuceConnectionFactory(config); } } ``` 4. **手动管理连接并实现切换逻辑**: 如果项目未使用高级客户端库或框架,可以手动管理 Redis 连接,并在需要时关闭旧连接并建立新连接。这种方式实现较为复杂,但灵活性更高。例如,可以在运行时检测配置变化,并在新请求到来时使用新的连接参数[^4]。 ```java // 假设 redisClient 是当前使用的连接实例 redisClient.shutdown(); // 关闭旧连接 redisClient = new RedisClient(RedisURI.create("redis://new_host:6379")); // 建立新连接 ``` 综上所述,通过连接池管理、服务发现、配置中心或手动连接切换,可以在不停止项目运行的情况下实现 Redis 连接地址的动态更新。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值