我正在尝试将 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
以下是解决此问题的步骤:
在任务中使 GoogleDriveFileHolder 不可为 Null: 确保
GoogleDriveFileHolder
中的 fileList
实例不可为 null。这可以通过在创建 Task
时显式指定类型不可为空并进行相应处理来实现。
更新 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)
}
}
}
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)
}
}
}