【问题标题】:How to use (or replace) java 8 functional interface with android API below 24?如何使用(或替换)java 8 功能接口与 24 以下的 android API?
【发布时间】:2018-01-10 08:55:00
【问题描述】:

我正在开发一个 android 应用程序 (minSdkVersion: 23)。 在我的登录方法中,我进行了这样的调用:

RequestClass.doRequestWithApi(this.getApplicationContext(), this.TAG, dataToPass, this::getMyAccount);

这里是 doRequestWithApi 方法:

public static void doRequestWithApi(Context c, final String TAG, final Map<String, String> paramsToPass, final Function<JSONObject,Boolean> f){

    String urlData = "http://...";
    //For localhost
    //String urlData = "http://10.0.2.2/...";

    Log.i(CAT,paramsToPass.toString());

    URL url = null;
    try {

        url = new URL(urlData);
        URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
        url = uri.toURL();

        Log.i(CAT, "Start Building");

        StringRequest jsObjRequest = new StringRequest(Request.Method.POST, url.toString(),
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        Log.i(CAT, "Reponse : " + response.toString() );
                        try {
                            f.apply(new JSONObject(response));
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Log.i(TAG, error.toString());
                    }
                }) {
            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                HashMap<String, String> map = new HashMap<String, String>();
                map.put("Accept-Language", Locale.getDefault().toString());
                return map;
            }

            @Override
            protected Map<String, String> getParams(){
                return paramsToPass;
            }

        };

        jsObjRequest.setRetryPolicy(new DefaultRetryPolicy(0, DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

        // Access the RequestQueue through your singleton class.
        MySingletonRequestApi.getInstance(c).addToRequestQueue(jsObjRequest, TAG);

    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (URISyntaxException e) {
        e.printStackTrace();
    }
}

如您所见,this::getMyAccount 是使用函数式接口,它是 java 8 的功能。

我找到了这个页面:Java 8 Android support 它表明 java.lang.FunctionalInterface 仅在 API 级别 24 或更高级别上受支持。 事实上,当我尝试在 6.0 android 设备(API 23)上运行我的应用程序时,它会抛出这个错误:

E/AndroidRuntime: FATAL EXCEPTION: main
              Process: etsymbiose.defdress, PID: 8296
              java.lang.NoClassDefFoundError: etsymbiose.defdress.LoginActivity$$Lambda$1
                  at etsymbiose.defdress.LoginActivity.onCreate(LoginActivity.java:51)
                  at android.app.Activity.performCreate(Activity.java:6301)
                  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1113)
                  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2519)
                  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2654)
                  at android.app.ActivityThread.-wrap11(ActivityThread.java)
                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1488)
                  at android.os.Handler.dispatchMessage(Handler.java:111)
                  at android.os.Looper.loop(Looper.java:207)
                  at android.app.ActivityThread.main(ActivityThread.java:5728)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)

我该如何解决这个问题?

【问题讨论】:

    标签: android java-8 method-reference functional-interface


    【解决方案1】:

    在您的应用级别build.gradle 文件中,您可以像这样指定compileOptions 块以使用Java-8 功能:

    android {
      ...
    
      compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
      }
    }
    

    【讨论】:

    • 这不完全是我在 build.gradle 文件中的内容。我确实有相同的 compileOptions 块,但有: targetCompatibility 1.8 sourceCompatibility 1.8 我猜是一样的。
    【解决方案2】:

    如果您使用的是 Android Studio,只需转到 File -&gt; Project Structure -&gt; app 并 将Source Compatibility 更改为1.8Target Compatibility 也更改为1.8,如下图所示:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-23
      • 1970-01-01
      • 1970-01-01
      • 2013-11-25
      • 2016-08-21
      • 1970-01-01
      相关资源
      最近更新 更多