天天看點

aidl.exe'' finished with non-zero exit value 1問題解決

PS:Android Studio用AIDL時,碰到一個非常棘手的問題,但是百度之,壓根非法解決,翻牆出去,終于找到了一篇解決問題的文章,特地轉載之。

之前使用aidl傳遞的都是基本的資料類型比如int 、boolean之類的還有就是String類型的參數,并沒有傳遞自己定義的class。 最近在開發的過程中重構代碼時遇到了這個問題,網上也有文章提供了解決的辦法,不過不太全面。我東拼西湊才把問題給解決了。這裡記錄一下。

一、直接在aidl中的方法參數傳遞一個自定義類參數。

看一下我們的aidl檔案

// IJDMAService.aidl
package com.jingdong.jdlogsys;

import com.jingdong.jdlogsys.model.CommonParamInfo;

interface IJDFileLogService {

    void setCommonParamInfo(CommonParamInfo info);
    void changeUser(String uid,String uuid,String pin);

}
           

這裡的setCommonParamInfo方法的參數就是一個我們自己定義的類CommonParamInfo,雖然上面import了這個類,但是編譯項目時會報如下的錯誤資訊(使用Android Studio)。

Error:Execution failed for task ':JDLogSys:compileReleaseAidl'.
> com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command 'D:\Android\sdk\build-tools\19.1.0\aidl.exe'' finished with non-zero exit value 1
Error:(5) couldn't find import for class com.jingdong.jdlogsys.model.CommonParamInfo
F:\JD_GIT\JDLogSys\JDLogSys\res\com\jingdong\jdlogsys\IJDFileLogService.aidl
           

看到這麼一行資訊 Error:(5) couldn't find import for class com.jingdong.jdlogsys.model.CommonParamInfo 。意思就是找不到這個類。

二、網上提供了一個解決這個問題的方法

首先建立一個CommonParamInfo.aidl檔案,檔案的内容如下:

package com.jingdong.jdlogsys.model;

parcelable CommonParamInfo;
      

要注意的是這裡的package要和原本定義的類的包名一樣,其次是下面的parcelable CommonParamInfo;這行代碼。

當然最重要的一點是你自己定義的類要實作Parcelable接口并按照規範重寫一系列方法。這裡我就不做介紹了。

接着重新編譯,是的不再報上面那個錯誤資訊,但是報了另外一個錯誤:

:JDLogSys:compileReleaseAidl
F:\JD_GIT\JDLogSys\JDLogSys\res\com\jingdong\jdlogsys\IJDFileLogService.aidl:14 parameter 1: 'CommonParamInfo info' can be an out parameter, so you must declare it as in, out or inout.
Error:Execution failed for task ':JDLogSys:compileReleaseAidl'.
> com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command 'D:\Android\sdk\build-tools\19.1.0\aidl.exe'' finished with non-zero exit value 1
      

看到這麼一行資訊IJDFileLogService.aidl:14 parameter 1: 'CommonParamInfo info' can be an out parameter, so you must declare it as in, out or inout.

意思就是我們需要把這個參數聲明成in或者inout類型的,

三、于是我們修改一下aidl中的setCommonParamInfo方法,一開始我是設定的inout:

void setCommonParamInfo(inout CommonParamInfo info);
      

于是,不出意外接着報錯:

Error:(144, 5) 錯誤: 找不到符号
符号:   方法 readFromParcel(Parcel)
位置: 類型為 CommonParamInfo 的變量 info
注: 有關詳細資訊, 請使用 -Xlint:deprecation 重新編譯。
Error:Execution failed for task ':JDLogSys:compileReleaseJava'.
> Compilation failed; see the compiler error output for details.
1 個錯誤
注: 某些輸入檔案使用或覆寫了已過時的 API。
F:\JD_GIT\JDLogSys\JDLogSys\build\generated\source\aidl\release\com\jingdong\jdlogsys\IJDFileLogService.java
      

啥狀況呢,就是說找不到readFromParcel方法。我看了一下CommonParamInfo類,确實沒有這個方法,但是之前該重寫的方法都重寫了啊,之前一直也是這麼做的。 于是我又接着搜尋,找到了解決這個問題的方法,就是在CommonParamInfo類中自己添加一個readFromParcel方法

四、修改CommonParamInfo類,添加readFromParcel方法

package com.jingdong.jdlogsys.model;

import android.os.Parcel;
import android.os.Parcelable;

/**
 * Created by zhengqing on 2014/12/18.
 */
public class CommonParamInfo implements Parcelable {
    public static final Parcelable.Creator<CommonParamInfo> CREATOR = new Creator<CommonParamInfo>() {
        @Override
        public CommonParamInfo[] newArray(int size) {
            return new CommonParamInfo[size];
        }

        @Override
        public CommonParamInfo createFromParcel(Parcel in) {
            return new CommonParamInfo(in);
        }
    };
    public String strUid;           //使用者id
    public String strUuid;          //使用者唯一辨別,根據裝置串号等唯一編碼

    public CommonParamInfo() {
        // TODO Auto-generated constructor stub
    }
    @SuppressWarnings("unchecked")
    public CommonParamInfo(Parcel in) {
        // TODO Auto-generated constructor stub
        strUid = in.readString();
        strUuid = in.readString();
    }
    public void readFromParcel(Parcel in){
        strUid = in.readString();
        strUuid = in.readString();
    }
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(strUid)
          .append(strUuid);
        return sb.toString();
    }
    public String getStrUid() {
        return strUid;
    }
    public void setStrUid(String strUid) {
        this.strUid = strUid;
    }
    public String getStrUuid() {
        return strUuid;
    }
    public void setStrUuid(String strUuid) {
        this.strUuid = strUuid;
    }
    @Override
    public int describeContents() {
        return 0;
    }
    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeString(strUid);
        out.writeString(strUuid);
    }
}
           

其實readFromParcel方法的實作和構造函數中的内容是一樣的。這樣我們再次編譯運作,發現沒有任何問題了。

五、接着我又把第三步中的inout修改成了in

發現并沒有報找不到readFromParcel方法的錯誤。

參考文章:

http://blog.csdn.net/jackyu613/article/details/6011606

http://blog.csdn.net/flowingflying/article/details/22276821

THE END.