类型不匹配:推断类型为 OnSuccessListener<ArrayList<myClass?>> 但 OnSuccessListener<in ArrayList<myClass>!> 是预期的

问题描述 投票:0回答:1

我正在尝试将 Java 代码转换为 Kotlin 代码,但特别是在代码段中,似乎不可能完全转换。

我收到构建错误:

类型不匹配 必需:OnSuccessListener 发现:OnSuccessListener>

该代码用于检索 Google Drive 中的文件夹。

我正在使用:

implementation 'com.google.android.gms:play-services-auth:19.0.0'
implementation 'com.google.http-client:google-http-client-gson:1.26.0'
implementation('com.google.api-client:google-api-client-android:1.26.0') {
    exclude group: 'org.apache.httpcomponents'
}
implementation('com.google.apis:google-api-services-drive:v3-rev136-1.25.0') {
    exclude group: 'org.apache.httpcomponents'
}

然后:

import com.google.android.gms.tasks.OnSuccessListener
import com.google.api.services.drive.Drive

这是类中的Java代码:

private static final String TAG = "GoogleDriveService";
private final Executor mExecutor = Executors.newSingleThreadExecutor();
private final Drive mDriveService;

private final String FOLDER_MIME_TYPE = "application/vnd.google-apps.folder";
private final String SHEET_MIME_TYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
private final String FOLDER_NAME = "Example_Folder";

public Task<ArrayList<GoogleDriveFileHolder>> getFolderFileList() {

    ArrayList<GoogleDriveFileHolder> fileList = new ArrayList<>();

    if (folderId.isEmpty()){
        Log.e(TAG, "getFolderFileList: folder id not present" );
        isFolderPresent().addOnSuccessListener(id -> folderId=id)
                .addOnFailureListener(exception -> Log.e(TAG, "Couldn't create file.", exception));
    }

    return Tasks.call(mExecutor, () -> {
        FileList result = mDriveService.files().list()
                .setQ("mimeType = '" + SHEET_MIME_TYPE + "' and trashed=false and parents = '" + folderId + "' ")
                .setSpaces("drive")
                .execute();

        for (int i = 0; i < result.getFiles().size(); i++) {
            GoogleDriveFileHolder googleDriveFileHolder = new GoogleDriveFileHolder();
            googleDriveFileHolder.setId(result.getFiles().get(i).getId());
            googleDriveFileHolder.setName(result.getFiles().get(i).getName());

            fileList.add(googleDriveFileHolder);
        }
        Log.e(TAG, "getFolderFileList: folderFiles: "+fileList );
        return fileList;
    });
}

使用Java代码:

public void getFolderData(View view) {
    if (mDriveServiceHelper != null) {
        Intent intent = new Intent(this, ListActivity.class);

        mDriveServiceHelper.getFolderFileList()
                .addOnSuccessListener(new OnSuccessListener<ArrayList<GoogleDriveFileHolder>>() {
                    @Override
                    public void onSuccess(ArrayList<GoogleDriveFileHolder> result) {
                        Log.e(TAG, "onSuccess: result: "+result.size() );
                        intent.putParcelableArrayListExtra("fileList", result);
                        startActivity(intent);
                    }
                })
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        showMessage("Not able to access Folder data.");
                        Log.e(TAG, "Not able to access Folder data.", e);
                    }
                });
    }
}

Java 中的类:

public class GoogleDriveFileHolder implements Parcelable {

private String id;
private String name;

public GoogleDriveFileHolder(){}

private GoogleDriveFileHolder(Parcel in) {
    id = in.readString();
    name = in.readString();
}

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

@Override
public int describeContents() {
    return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(id);
    dest.writeString(name);
}

public static final Creator<GoogleDriveFileHolder> CREATOR
        = new Creator<GoogleDriveFileHolder>() {
    public GoogleDriveFileHolder createFromParcel(Parcel in) {
        return new GoogleDriveFileHolder(in);
    }

    public GoogleDriveFileHolder[] newArray(int size) {
        return new GoogleDriveFileHolder[size];
    }
};

}

这是 Kotlin 的翻译代码:

private val mExecutor: Executor = Executors.newSingleThreadExecutor()
private val mDriveService: Drive = driveService

private val FOLDER_MIME_TYPE = "application/vnd.google-apps.folder"
private val SHEET_MIME_TYPE =
    "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
private val FOLDER_NAME = "Example_Folder"


val getFolderFileList: Task<java.util.ArrayList<GoogleDriveFileHolder>>
    /**
     * Get all the file present in the user's My Drive Folder.
     */
    get() {
        val fileList = java.util.ArrayList<GoogleDriveFileHolder>()

        if (folderId.isEmpty()) {
            Log.e(TAG, "getFolderFileList: folder id not present")
            isFolderPresent.addOnSuccessListener { id: String -> folderId = id }
                .addOnFailureListener { exception: Exception? ->
                    Log.e(
                        TAG,
                        "Couldn't create file.",
                        exception
                    )
                }
        }

        return Tasks.call(mExecutor) {
            val result: FileList = mDriveService.files().list()
                .setQ("mimeType = '$SHEET_MIME_TYPE' and trashed=false and parents = '$folderId' ")
                .setSpaces("drive")
                .execute()
            for (i in result.files.indices) {
                val googleDriveFileHolder = GoogleDriveFileHolder()
                googleDriveFileHolder.id = result.files[i].id
                googleDriveFileHolder.name = result.files[i].name

                fileList.add(googleDriveFileHolder)
            }
            Log.e(TAG, "getFolderFileList: folderFiles: $fileList")
            fileList
        }
    }

这是使用 Kotlin 中的代码:

fun getFolderData(view: View?) {
    if (mDriveServiceHelper != null) {
        val intent = Intent(this, ListActivity::class.java)

        ////// Below line code has the build error:
        //// Type mismatch: inferred type is OnSuccessListener<ArrayList<GoogleDriveFileHolder?>> but OnSuccessListener<in ArrayList<GoogleDriveFileHolder>!> was expected

        mDriveServiceHelper!!.getFolderFileList
            .addOnSuccessListener(OnSuccessListener<ArrayList<GoogleDriveFileHolder?>> { result ->
                Log.e(TAG, "onSuccess: result: " + result.size)
                intent.putParcelableArrayListExtra("fileList", result)
                startActivity(intent)
            })
            .addOnFailureListener { e ->
                showMessage("Not able to access Folder data.")
                Log.e(TAG, "Not able to access Folder data.", e)
            }
    }
}

Kotlin 类:

class GoogleDriveFileHolder : Parcelable {
var id: String? = null
var name: String? = null

constructor()

private constructor(`in`: Parcel) {
    id = `in`.readString()
    name = `in`.readString()
}

override fun describeContents(): Int {
    return 0
}

override fun writeToParcel(dest: Parcel, flags: Int) {
    dest.writeString(id)
    dest.writeString(name)
}

companion object CREATOR : Creator<GoogleDriveFileHolder> {
    override fun createFromParcel(parcel: Parcel): GoogleDriveFileHolder {
        return GoogleDriveFileHolder(parcel)
    }

    override fun newArray(size: Int): Array<GoogleDriveFileHolder?> {
        return arrayOfNulls(size)
    }
}

}

构建错误:

Type mismatch: inferred type is OnSuccessListener<ArrayList<GoogleDriveFileHolder?>> but OnSuccessListener<in ArrayList<GoogleDriveFileHolder>!> was expected

///// Originally the error was as below but I qualified the ArrayList to java.util.ArrayList :
Type mismatch: inferred type is OnSuccessListener<java.util.ArrayList<GoogleDriveFileHolder?>> but OnSuccessListener<in kotlin.collections.ArrayList<GoogleDriveFileHolder> /* = java.util.ArrayList<GoogleDriveFileHolder> */!> was expected
java kotlin google-cloud-platform arraylist type-conversion
1个回答
0
投票

以下是解决此问题的步骤:

  1. 在任务中使 GoogleDriveFileHolder 不可为 Null: 确保

    GoogleDriveFileHolder
    中的
    fileList
    实例不可为 null。这可以通过在创建
    Task
    时显式指定类型不可为空并进行相应处理来实现。

  2. 更新 getFolderFileList 属性 更改

    getFolderFileList
    属性以确保列表不包含可为 null 的类型。您可以通过将类型指定为
    ArrayList<GoogleDriveFileHolder>
    而不是
    ArrayList<GoogleDriveFileHolder?>
    来完成此操作。

更新代码:

*Kotlin 代码 - *

private val mExecutor: Executor = Executors.newSingleThreadExecutor()
private val mDriveService: Drive = driveService

private val FOLDER_MIME_TYPE = "application/vnd.google-apps.folder"
private val SHEET_MIME_TYPE =
    "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
private val FOLDER_NAME = "Example_Folder"

val getFolderFileList: Task<ArrayList<GoogleDriveFileHolder>>
    get() {
        val fileList = ArrayList<GoogleDriveFileHolder>()

    if (folderId.isEmpty()) {
        Log.e(TAG, "getFolderFileList: folder id not present")
        isFolderPresent.addOnSuccessListener { id: String -> folderId = 
        id }
            .addOnFailureListener { exception: Exception? ->
                Log.e(
                    TAG,
                    "Couldn't create file.",
                    exception
                )
            }
    }

    return Tasks.call(mExecutor) {
        val result: FileList = mDriveService.files().list()
            .setQ("mimeType = '$SHEET_MIME_TYPE' and trashed=false and 
             parents = '$folderId' ")
            .setSpaces("drive")
            .execute()
        for (i in result.files.indices) {
            val googleDriveFileHolder = GoogleDriveFileHolder()
            googleDriveFileHolder.id = result.files[i].id
            googleDriveFileHolder.name = result.files[i].name

            fileList.add(googleDriveFileHolder)
        }
        Log.e(TAG, "getFolderFileList: folderFiles: $fileList")
        fileList
    }
}

fun getFolderData(view: View?) {
    if (mDriveServiceHelper != null) {
        val intent = Intent(this, ListActivity::class.java)

        mDriveServiceHelper!!.getFolderFileList
            .addOnSuccessListener(OnSuccessListener { result ->
                Log.e(TAG, "onSuccess: result: " + result.size)
            intent.putParcelableArrayListExtra("fileList", result)
            startActivity(intent)
        })
        .addOnFailureListener { e ->
            showMessage("Not able to access Folder data.")
            Log.e(TAG, "Not able to access Folder data.", e)
        }
   }
}
  1. 确保
    GoogleDriveFileHolder
    中的类型不可为空: 在您的
    GoogleDriveFileHolder
    类中,确保属性
    id
    name
    不可为空(如果它们不应为空):

Kotlin 代码 -

class GoogleDriveFileHolder : Parcelable {
    var id: String = ""
    var name: String = ""

    constructor()

    private constructor(parcel: Parcel) {
        id = parcel.readString() ?: ""
        name = parcel.readString() ?: ""
    }

    override fun describeContents(): Int {
        return 0
    }

    override fun writeToParcel(dest: Parcel, flags: Int) {
        dest.writeString(id)
        dest.writeString(name)
    }

    companion object CREATOR : Parcelable.Creator<GoogleDriveFileHolder> {
        override fun createFromParcel(parcel: Parcel): GoogleDriveFileHolder {
            return GoogleDriveFileHolder(parcel)
        }

        override fun newArray(size: Int): Array<GoogleDriveFileHolder?> {
            return arrayOfNulls(size)
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.