android 双SD卡切换(SD SWAP) 方案,如何恢复“设置->存储->默认存储器”的用户选择功...


修改涉及到的文件:
- package/app/settings/。。。/deviceinfo/Memory.java:恢复“默认存储器”的选择功能
- StorageManager.java的getDefaultPath()方法:取得“默认存储器”的实际路径


针对ICS2版本:
1. 修改package/app/settings/。。。/deviceinfo/Memory.java

修改点:下面的代码可能跟贵司现有的代码不一致,但思路是一样的,即: 把原来通过FeatureOption.MTK_SWAP_STATIC_MODE包着的“移除默认存储器选择功能”的代码段disable掉,如下:

public void onCreate(Bundle icicle) {
. . . . . .
if(FeatureOption.MTK_2SDCARD_SWAP) {

//把判断条件里的FeatureOption.MTK_SWAP_STATIC_MODE修改成false
if(FeatureOption.MTK_SWAP_STATIC_MODE) à false

{
getPreferenceScreen().removePreference(mDefaultWriteCategory);
}
IntentFilter mFilter = new IntentFilter();
mFilter.addAction(ACTION_DYNAMIC_SD_SWAP);
getActivity().registerReceiver(mDynSwapReceiver, mFilter);
}
}

. . . . . .

public void onResume() {
....

// 把判断条件里的FeatureOption.MTK_SWAP_STATIC_MODE修改成false
// if(!(FeatureOption.MTK_2SDCARD_SWAP && FeatureOption.MTK_SWAP_STATIC_MODE)) { à false
dynamicShowDefaultWriteCategory();
}

---------

public boolean onPreferenceChange(Preference preference, Object newValue){
//把判断条件里的FeatureOption.MTK_SWAP_STATIC_MODE修改成false if(FeatureOption.MTK_2SDCARD_SWAP && FeatureOption.MTK_SWAP_STATIC_MODE) { à false
return false;
}
if (preference != null && preference instanceof RadioButtonPreference) {
if(mDeafultWritePathPref != null) {
mDeafultWritePathPref.setChecked(false);
}
mStorageManager.setDefaultPath(preference.getKey());
mDeafultWritePathPref = (RadioButtonPreference)preference;
return true;
}
return false;
}

private final Runnable mUpdateRunnable = new Runnable() {
public void run() {
//把判断条件里的FeatureOption.MTK_SWAP_STATIC_MODE修改成false
if(!(FeatureOption.MTK_2SDCARD_SWAP && FeatureOption.MTK_SWAP_STATIC_MODE) ) { à false
dynamicShowDefaultWriteCategory();
}
}
};
. . . . . .

2. StorageManager.java
把getDefaultPath()方法改成以下这样:
public static String getDefaultPath() {
String path = DEFAULT_PATH;
try {
path = SystemProperties.get(PROP_SD_DEFAULT_PATH, DEFAULT_PATH);
} catch (IllegalArgumentException e) {
Log.e(TAG, "IllegalArgumentException when get default path:"+e);
}

Log.i(TAG, "getDefaultPath path="+path);
return path;
}:
. . . . . .

针对ICS版本:
1. 修改package/app/settings/。。。/deviceinfo/Memory.java
下面的代码可能跟贵司现有的代码不一致,但思路是一样的,即: 把原来通过FeatureOption. MTK_2SDCARD_SWAP包着的“移除默认存储器选择功能”的代码段enable,如下:

主要有以下修改点:
// 把判断条件里的!FeatureOption.MTK_2SDCARD_SWAP修改成true,让代码可以被执行到
if(!FeatureOption.MTK_2SDCARD_SWAP) { à true
dynamicShowDefaultWriteCategory();
}
. . . . . .
public boolean onPreferenceChange(Preference preference, Object newValue){
//把判断条件里的FeatureOption.MTK_2SDCARD_SWAP修改成false,让代码不要被执行到
if(FeatureOption.MTK_2SDCARD_SWAP) { à false

return false;
}
. . . . . .

//把判断条件里的FeatureOption.MTK_2SDCARD_SWAP修改成false,让代码不要被执行到
if(FeatureOption.MTK_2SDCARD_SWAP) { à false
getPreferenceScreen().removePreference(mDefaultWriteCategory);
}
. . . . . .

2. StorageManager.java
把getDefaultPath()方法改成以下这样:
public static String getDefaultPath() {
String path = DEFAULT_PATH;

try {
path = SystemProperties.get(PROP_SD_DEFAULT_PATH, DEFAULT_PATH);
} catch (IllegalArgumentException e) {
Log.e(TAG, "IllegalArgumentException when get default path:"+e);
}

Log.i(TAG, "getDefaultPath path="+path);
return path;
}

<think>我们正在讨论的是`cb.swap(thread->m_cb)`的使用或问题解决方法。这里的`cb`和`thread->m_cb`可能是两个容器或缓冲区对象,常见于C++中,尤其是多线程环境下进行数据交换以避免锁的开销。在C++中,`swap`成员函数通常用于交换两个相同类型对象的内容,这个操作在常数时间内完成,并且不会抛出异常(对于标准库容器如`std::vector`等是如此)。在多线程编程中,使用`swap`可以快速地将线程内的数据与外部传递的数据进行交换,从而减少锁的占用时间。假设`thread->m_cb`是线程内部的一个缓冲区(比如一个`std::vector`或自定义的缓冲区类),而`cb`是外部传入的另一个缓冲区。那么`cb.swap(thread->m_cb)`的作用是将外部缓冲区`cb`与线程内部缓冲区`thread->m_cb`进行内容交换。###典型使用场景1.**生产者-消费者模型**:当消费者线程需要处理数据时,生产者可以通过交换将数据快速传递给消费者线程,而无需长时间加锁。```cpp//假设在生产者线程中{std::lock_guard<std::mutex>lock(shared_mutex);//将生产好的数据交换到共享缓冲区local_buffer.swap(shared_buffer);}//然后通知消费者线程```消费者线程在唤醒后,可以交换共享缓冲区和自己的本地缓冲区:```cpp//消费者线程{std::lock_guard<std::mutex>lock(shared_mutex);//将共享缓冲区的数据交换到本地shared_buffer.swap(thread->m_cb);}//处理交换得到的数据(thread->m_cb现在持有之前shared_buffer的数据)```2.**缓冲区技术**:在需要连续处理数据且避免锁的场合(如实时图形渲染),常使用缓冲区。一个缓冲区用于后台处理,另一个用于前台显示。通过交换操作,可以快速切换前后台缓冲区。###可能的问题及解决方法1.**线程安全问题**:如果`cb`和`thread->m_cb`的交换操作不是在锁的保护下进行,可能会导致数据竞争。解决方法:确保在交换操作时持有适当的互斥锁。2.**资源管理问题**:交换后,原来`cb`中的内容变成了`thread->m_cb`之前的内容,需要确保在交换后能正确地清理或处理这些内容。例如,如果交换的是拥有大量内存的容器,那么交换后需要及时释放不再需要的内存。3.**性能问题**:虽然`swap`操作本身很快(常数时间),但如果在临界区内进行交换操作,且交换的数据量很大(比如交换的是两个很大的容器),那么临界区的执行时间会变长,从而影响并发性能。解决方法:尽量减小临界区的范围,只交换必要的部分。4.**对象生命周期问题**:如果`thread->m_cb`所指向的对象可能被销毁(比如线程结束时),那么在交换时需要确保对象仍然有效。特别是在线程即将退出时,避免交换操作。###代码示例以下是一个简化的缓冲区交换示例:```cpp#include<vector>#include<mutex>classThreadData{public:std::vector<int>m_cb;};voidswapBuffers(std::vector<int>&cb,ThreadData*thread,std::mutex&mtx){std::lock_guard<std::mutex>lock(mtx);//交换缓冲区cb.swap(thread->m_cb);}intmain(){std::mutexmtx;std::vector<int>producer_buffer;ThreadDataconsumer_thread_data;//假设生产者填充了producer_bufferproducer_buffer={1,2,3,4,5};//将生产者的缓冲区与消费者线程的缓冲区交换swapBuffers(producer_buffer,&consumer_thread_data,mtx);//现在producer_buffer变为交换前consumer_thread_data.m_cb的内容(可能是空的)//而consumer_thread_data.m_cb持有{1,2,3,4,5}return0;}```###注意事项-确保交换的方类型相同,否则编译失败。-对于自定义类型,确保实现了`swap`方法并且是高效且异常安全的。-在多线程环境下,确保正确使用同步原语(如互斥锁)保护交换操作。如果具体问题中涉及特定的使用场景或错误,需要根据实际情况分析。§§相关问题§§1.C++中`std::swap`和成员函数`swap`有什么区别?2.如何为自定义类实现高效的`swap`操作?3.缓冲区技术在多线程编程中还有哪些应用?4.如何避免在交换缓冲区时发生资源泄露?</think> ### 使用 `cb.swap(thread->m_cb)` 的分析与解决方法 #### 能分析 `cb.swap(thread->m_cb)` 是 C++ 中的标准操作,作用是在两个同类型容器间交换内容: 1. **高效交换**:$O(1)$ 时间复杂度操作指针/迭代器,适用于 `std::vector`, `std::list` 等容器[^1] 2. **资源转移**:将 `cb` 的数据完全转移到 `thread->m_cb`,同时将原 `thread->m_cb` 数据转移到 `cb` 3. **多线程场景**:常用于生产者-消费者模型中避免数据拷贝的开销 #### 典型使用场景 ```cpp // 生产者线程 void producer() { std::vector<int> local_buffer; // ... 填充数据 ... { std::lock_guard<std::mutex> lock(shared_mutex); local_buffer.swap(shared_buffer); // 原子交换 } } // 消费者线程 void consumer() { std::vector<int> local_buffer; { std::lock_guard<std::mutex> lock(shared_mutex); shared_buffer.swap(local_buffer); // 原子交换 } // 处理 local_buffer 数据 } ``` #### 常见问题与解决方法 1. **线程安全问题** - ❌ 问题:无锁交换导致数据竞争 - ✅ 解决:使用互斥锁保护交换操作 ```cpp std::mutex mtx; { std::lock_guard<std::mutex> lock(mtx); cb.swap(thread->m_cb); } ``` 2. **内存泄漏风险** - ❌ 问题:自定义容器未正确实现 `swap` - ✅ 解决:确保容器实现标准交换语义 ```cpp class MyBuffer { public: void swap(MyBuffer& other) noexcept { std::swap(data_, other.data_); std::swap(size_, other.size_); } }; ``` 3. **生命周期问题** - ❌ 问题:线程终止后访问 `thread->m_cb` - ✅ 解决:增加生命周期检查 ```cpp if (!thread->is_finished) { cb.swap(thread->m_cb); } ``` 4. **性能异常** - ❌ 问题:大量小对象频繁交换导致CPU缓存失效 - ✅ 解决:批处理交换操作 ```cpp if (cb.size() > BATCH_SIZE) { cb.swap(thread->m_cb); } ``` #### 最佳实践 1. **配合智能指针** 实现所有权安全转移: ```cpp std::shared_ptr<Buffer> cb = std::make_shared<Buffer>(); cb.swap(thread->m_cb_ptr); // 所有权安全转移 ``` 2. **缓冲技术** 减少锁竞争: ```cpp // 线程内维护两个缓冲区 Buffer* active = &buf1; Buffer* standby = &buf2; // 交换时仅交换指针 std::swap(active, standby); ``` 3. **异常安全保证**: ```cpp try { cb.swap(thread->m_cb); } catch (...) { // 回滚或日志处理 } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值