新浪微博 SDK `userTimelineIds` 使用內部 `AsyncTask` 實現非同步回調,`onComplete(String result)` 執行於**背景執行緒**(或 SDK 內部執行緒池),**不能直接操作 UI**。需將資料傳遞到主執行緒(`runOnUiThread`、`Handler`、`LiveData`)後再設定 `ListView` Adapter。
mStatuseAPI.userTimelineIds(uid, ..., new RequestListener() {
@Override
public void onComplete(String result) {
// ❌ 這裡可能在背景執行緒,直接操作 ListView 會崩潰或不生效
getWbList(result); // 內部可能呼叫 adapter.notifyDataSetChanged()
}
});
| 方案 | 代碼範例 | 優點 | 缺點 |
|---|---|---|---|
| runOnUiThread | `runOnUiThread(() -> getWbList(result));` | 簡單、無額外依賴 | Activity 銷毀後可能洩漏 |
| Handler (主執行緒 Looper) | `new Handler(Looper.getMainLooper()).post(() -> getWbList(result));` | 可在非 Activity 類別使用 | 需持有 Looper 參考 |
| LiveData + ViewModel (推薦) | ViewModel 持有 `MutableLiveData
| 生命週期感知、配置變更安全、可測試 | 需引入 Architecture Components |
| RxJava / Kotlin Coroutines | `Single.fromCallable(...).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())` | 鏈式、背壓、取消支援 | 學習曲線較高 |
mStatuseAPI.userTimelineIds(uid, 0L, 0L, 50, 1, false, StatusesAPI.FEATURE_ALL,
new RequestListener() {
@Override
public void onWeiboException(WeiboException e) { e.printStackTrace(); }
@Override
public void onComplete(String result) {
if (TextUtils.isEmpty(result)) {
Log.i(TAG, "無微博資料");
return;
}
// ✅ 切回主執行緒更新 UI
runOnUiThread(() -> {
try {
getWbList(result); // 解析 JSON、填充 List、adapter.notifyDataSetChanged()
} catch (Exception e) {
e.printStackTrace();
}
});
}
});
private void getWbList(String json) {
try {
JSONObject obj = new JSONObject(json);
JSONArray ids = obj.getJSONArray("ids"); // 視 API 實際結構
List items = new ArrayList<>();
for (int i = 0; i < ids.length(); i++) {
String id = ids.getString(i);
// 這裡可再發請求查詢微博詳情,或直接用 ID 佔位
items.add(new WeiboItem(id, "內容載入中..."));
}
// 更新 Adapter
if (adapter == null) {
adapter = new WeiboAdapter(this, items);
listView.setAdapter(adapter);
} else {
adapter.clear();
adapter.addAll(items);
adapter.notifyDataSetChanged();
}
} catch (JSONException e) { e.printStackTrace(); }
}
// ViewModel
public class WeiboViewModel extends ViewModel {
private final MutableLiveData> _weiboList = new MutableLiveData<>();
public LiveData> weiboList = _weiboList;
public void fetchWeiboIds(long uid) {
mStatuseAPI.userTimelineIds(uid, ..., new RequestListener() {
@Override public void onComplete(String result) {
List list = parseResult(result);
_weiboList.postValue(list); // 自動切主執行緒
}
@Override public void onWeiboException(WeiboException e) {
_weiboList.postValue(Collections.emptyList());
}
});
}
}
// Activity/Fragement
viewModel.weiboList.observe(getViewLifecycleOwner(), items -> {
adapter.submitList(items); // ListAdapter / DiffUtil 自動動畫
});
在 `onComplete` 回調中用 `runOnUiThread(() -> getWbList(result))` 即可快速修復;長期專案建議遷移至 `ViewModel + LiveData` 或 `Kotlin Coroutines` 獲得完整生命週期管理。