我目前正在通过在线Udemy android课程工作,并遇到了ListLoader的这段代码
package com.kencephalon.friends;
import android.content.AsyncTaskLoader;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.BaseColumns;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
public class FriendsListLoader extends AsyncTaskLoader<List<Friend>> {
public static final String LOG_TAG = FriendsListLoader.class.getSimpleName();
private List<Friend> mFriends;
private ContentResolver mContentResolver;
private Cursor mCursor;
public FriendsListLoader(Context context , Uri uri, ContentResolver contentResolver){
super(context);
mContentResolver = contentResolver;
}
//Retrieves all the records
public List<Friend> loadInBackground() {
String[] projection = {BaseColumns._ID,
FriendsContract.FriendsColumn.FRIENDS_NAME,
FriendsContract.FriendsColumn.FRIENDS_PHONE,
FriendsContract.FriendsColumn.FRIENDS_EMAIL};
List<Friend> entries = new ArrayList<Friend>();
mCursor = mContentResolver.query(FriendsContract.URI_TABLE,projection,null,null,null);
if(mCursor != null){
if(mCursor.moveToFirst()){
do {
int _id = mCursor.getInt(mCursor.getColumnIndex(BaseColumns._ID));
String name = mCursor.getString(mCursor.getColumnIndex(FriendsContract.FriendsColumn.FRIENDS_NAME));
String phone = mCursor.getString(mCursor.getColumnIndex(FriendsContract.FriendsColumn.FRIENDS_PHONE));
String email = mCursor.getString(mCursor.getColumnIndex(FriendsContract.FriendsColumn.FRIENDS_EMAIL));
Friend friend = new Friend(_id,name,phone,email);
entries.add(friend);
}while (mCursor.moveToNext());
}
}
return entries;
}
@Override
public void deliverResult(List<Friend> friends) {
if(isReset()){
if(mFriends != null){
mCursor.close();
}
}
List<Friend> oldFriendsList = mFriends;
if(mFriends == null || mFriends.size() == 0){
Log.d(LOG_TAG,"+++++++++ No Data Returned");
}
mFriends = friends;
if(isStarted()){
super.deliverResult(friends);
}
if(oldFriendsList != null && oldFriendsList != friends ){
mCursor.close();
}
}
@Override
protected void onStartLoading() {
if(mFriends != null){
deliverResult(mFriends);
}
//Checks if the data has changed when the load was stopped or if there is no data and forces a reload
if(takeContentChanged() || mFriends == null){
forceLoad();
}
}
@Override
protected void onStopLoading() {
cancelLoad();
}
@Override
protected void onReset() {
onStopLoading();
if(mCursor != null){
mCursor.close();
}
mFriends = null;
}
@Override
public void onCanceled(List<Friend> friends) {
super.onCanceled(friends);
if(mCursor != null){
mCursor.close();
}
}
@Override
public void forceLoad() {
super.forceLoad();
}
}
从重写方法deliverResult开始的代码部分让我感到困惑,特别是当代码测试mFriends == null或mFriends.size()== 0时。
从代码示例中可以看出,mFriends仅在最顶层声明了以下行
private List<Friend> mFriends;
并没有做任何事情。既然如此,那么mFriends不应该没有值,这将导致检查
if(mFriends == null || mFriends.size() == 0){
Log.d(LOG_TAG,"+++++++++ No Data Returned");
}
没有意义,因为每次方法deliverResult都会记录Log.d消息,因为if语句会一直返回true,所以会调用0吗?
此外,我没有在代码部分中看到原因
if(oldFriendsList != null && oldFriendsList != friends ){
mCursor.close();
}
因为oldFriendsList(值为mFriends)将返回true,因为mFriends将等于null。
因此,我也不理解onStartLoading方法,其中程序检查mFriends!= null并调用deliverResult(mFriends),然后检查takeContentChanged()或mFriends == null,如下面的代码提取所示因为mFriends已被onReset()
设置为nullprotected void onStartLoading() {
if(mFriends != null){
deliverResult(mFriends);
}
//Checks if the data has changed when the load was stopped or if there is no data and forces a reload
if(takeContentChanged() || mFriends == null){
forceLoad();
}
}
QN:虽然我理解mFriends == null的检查很可能是由于onReset设置方法设置为mFriends = null,每当第一次调用加载器(重置)并在后续重置时,我的理解就会发生()调用, mFriends的值不会总是等于null并且永远不会被更改,这会使整个代码变得毫无意义吗?
我有一种感觉,我错过了一些东西,但我似乎无法弄清楚到底是什么,我错过了。任何澄清都将非常感谢!