Android開發(fā)問題匯總

1. 調(diào)試和解決Bug的經(jīng)驗

1)遇到錯誤問題時候、如果是小眾開源庫 可以直接到issue中找到對應的問題。
2)如果沒有,在StackOverflow上可以輕松找到。優(yōu)先Google、少用Baidu。
3)普通的空指針異常定位到對象即可解決。
4)盡可能地讓一個類、一個方法塊只干一件事情,耦合太嚴重,可以拆分接口、類。否則會導致莫名奇妙的問題,并且難以看懂,降低效率和提升維護難度。
5)斷點調(diào)試時候追蹤代碼問題是基本要求。
性能問題需要結(jié)合profiler 查看內(nèi)存、CPU占用情況,并且結(jié)合 火焰圖 FlameChart來查看可能的問題代碼塊。

2. 嵌套的RecyclerView滑動無響應的情況。

當滑動父RecyclerView的時候子RecyclerView可能沒有響應,或者滑動卡頓。解決方案,剛開始考慮的是事件沖突的解決方案,外部RecyclerView全部攔截操作,或者內(nèi)部攔截的方式設(shè)定dispatchTouchEvent。
由于它們是同方向的展示和滑動,而子RecyclerView需要展示的內(nèi)容并不是非常多,因而自定義了一個新的LinearLayoutManager,禁止它的垂直滑動操作。因而不用重寫兩個RecyclerView并且效果良好。

public class CustomLinearLayoutManager extends LinearLayoutManager {
    public CustomLinearLayoutManager(Context context) {
        super(context);
    }

    @Override
    public boolean canScrollVertically() {
        return false;
    }
}
3. 莫名的網(wǎng)絡加載不成功問題

Failed to connect to api.ioneball.com/139.224.7.244:443
https、http請求問題。當改為http時成功訪問

4. 垂直滑動的ViewPager一點小問題

重寫Viewpager時候,把橫向滑動的邏輯部分復用改成了能夠縱向垂直的邏輯。
動態(tài)刷新數(shù)據(jù)時不能夠成功讓pageradapter數(shù)據(jù)增加,并且在滑動到pageradapter中 size臨界大小的時候,報空指針異常。
查看自己變更的源碼發(fā)現(xiàn),問題出在沒有DataSetObserver,它為null,那么viewpager和pagerAdapter更新數(shù)據(jù)的橋梁也就斷了。
產(chǎn)生問題的原因是由于,新定義的viewpager和pagerAdapter不在一個包中,而關(guān)鍵的綁定二者的方法 setViewPagerObserver也就不能直接調(diào)用了,所以DataSetObserver為null。當時采用的是反射的方式調(diào)用關(guān)聯(lián)observer。

           if (mObserver == null) {
                mObserver = new PagerObserver();
            }
            try {
                Class<? extends PagerAdapter> aClass = mAdapter.getClass();
                Method method = aClass.getMethod("setViewPagerObserver");
                method.invoke(mAdapter, mObserver);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }

斷點調(diào)試發(fā)現(xiàn)總是走到了 NoSuchMethodException的部分。
所以重新查看了官方文檔的API,發(fā)現(xiàn)了 registerDataSetObserver 方法。
將 Method method = aClass.getMethod("setViewPagerObserver"); 改為下面這句
Method method = aClass.getMethod("registerDataSetObserver", DataSetObserver.class);
即可成功調(diào)用了。

    /**
     * Register an observer to receive callbacks related to the adapter's data changing.
     *
     * @param observer The {@link android.database.DataSetObserver} which will receive callbacks.
     */
    public void registerDataSetObserver(DataSetObserver observer) {
        mObservable.registerObserver(observer);
    }

    /**
     * Unregister an observer from callbacks related to the adapter's data changing.
     *
     * @param observer The {@link android.database.DataSetObserver} which will be unregistered.
     */
    public void unregisterDataSetObserver(DataSetObserver observer) {
        mObservable.unregisterObserver(observer);
    }

    void setViewPagerObserver(DataSetObserver observer) {
        synchronized (this) {
            mViewPagerObserver = observer;
        }
    }

源碼中三者是寫在一起的。

5. EventBus 無法更新UI?

斷點發(fā)現(xiàn)能夠成功傳遞數(shù)據(jù)。而界面UI卻并不能夠及時更新。
原因就是重新回到界面時,控件尚未被綁定就傳遞進了數(shù)據(jù)。數(shù)據(jù)就先于控件了。

6. Realm數(shù)據(jù)庫報錯情況

Each element of 'value' must be a valid managed object.
解決方式:

public class Product extends RealmObject {
     private RealmList<RecipientData> mRecipients;

     public void setRecipients(RealmList<RecipientData> mRecipientDatas) {
        this.mRecipients = mRecipientDatas;
     }

    public void addRecipient(RecipientData recipientData){
        if(mRecipients != null){
            mRecipients.add(recipientData);
        }
    }

    public void clearRecipients() {
        mRecipients = new RealmList<>();
    }
}

而不要在代碼當中 new RealmList<>() 如下:

try(Realm realm = Realm.getDefaultInstance()) {
    realm.executeTransaction(new Realm.Transaction() {
        @Override
        public void execute(Realm realm) {
            RealmProductModel managedProductModel = realm.copyToRealm(originalProductModel);
            // managedProductModel.clearRecipients(); // calls mRecipients = new RealmList<>();

            List<RecipientData> unmanagedRecipientDatas = realm.copyFromRealm(productModel.getRecipients());
            for(RecipientData recipientData : unmanagedRecipientDatas) {
                recipientData.setFloatingRecipient(true);
                recipientData.setId(getNextKey(RecipientData.class));
            }
            // 不要這樣操作
            RealmList<RecipientData> newRealmList = new RealmList<>(); 
            newRealmList.addAll(unmanagedRecipientDatas);
            managedProductModel.setRecipients(newRealmList);
        }
    });
}

應當這樣:

try(Realm realm = Realm.getDefaultInstance()) {
    realm.executeTransaction(new Realm.Transaction() {
        @Override
        public void execute(Realm realm) {
            RealmProductModel managedProductModel = realm.copyToRealm(originalProductModel);
            managedProductModel.clearRecipients(); // calls mRecipients = new RealmList<>();

            List<RecipientData> unmanagedRecipientDatas = realm.copyFromRealm(originalProductModel.getRecipients());
            for(RecipientData recipientData : unmanagedRecipientDatas) {
                recipientData.setFloatingRecipient(true);
                recipientData.setId(getNewKey(RecipientData.class));
                managedProductModel.addRecipient(recipientData);
            }
        }
    });
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容