android 模拟器在 Retrofit CallBack 中崩溃

标签 android api callback crash retrofit

我将在 Android 中使用 API 进行天气预报。当我运行程序时,模拟器在代码之后崩溃

mService.getAnswers().enqueue(new Callback<SOAnswerResponse>()

所以 onResponse 或 onFailure 方法都没有执行! 为什么会发生这种情况?我对 StackOverFlow Questions API 示例使用了相同的代码,并且它有效。

日志猫:

08-17 19:29:20.747 6012-6031/? E/AndroidRuntime: FATAL EXCEPTION: OkHttp Dispatcher
                                                 Process: com.example.asus.weather, PID: 6012
                                                 java.lang.SecurityException: Permission denied (missing INTERNET permission?)
                                                     at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:119)
                                                     at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:74)
                                                     at java.net.InetAddress.getAllByName(InetAddress.java:752)
                                                     at okhttp3.Dns$1.lookup(Dns.java:39)
                                                     at okhttp3.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:173)
                                                     at okhttp3.internal.http.RouteSelector.nextProxy(RouteSelector.java:139)
                                                     at okhttp3.internal.http.RouteSelector.next(RouteSelector.java:81)
                                                     at okhttp3.internal.http.StreamAllocation.findConnection(StreamAllocation.java:172)
                                                     at okhttp3.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:123)
                                                     at okhttp3.internal.http.StreamAllocation.newStream(StreamAllocation.java:93)
                                                     at okhttp3.internal.http.HttpEngine.connect(HttpEngine.java:296)
                                                     at okhttp3.internal.http.HttpEngine.sendRequest(HttpEngine.java:248)
                                                     at okhttp3.RealCall.getResponse(RealCall.java:243)
                                                     at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:201)
                                                     at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:163)
                                                     at okhttp3.RealCall.access$100(RealCall.java:30)
                                                     at okhttp3.RealCall$AsyncCall.execute(RealCall.java:127)
                                                     at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
                                                     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
                                                     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
                                                     at java.lang.Thread.run(Thread.java:761)
                                                  Caused by: android.system.GaiException: android_getaddrinfo failed: EAI_NODATA (No address associated with hostname)
                                                     at libcore.io.Posix.android_getaddrinfo(Native Method)
                                                     at libcore.io.ForwardingOs.android_getaddrinfo(ForwardingOs.java:55)
                                                     at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:106)
                                                     at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:74) 
                                                     at java.net.InetAddress.getAllByName(InetAddress.java:752) 
                                                     at okhttp3.Dns$1.lookup(Dns.java:39) 
                                                     at okhttp3.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:173) 
                                                     at okhttp3.internal.http.RouteSelector.nextProxy(RouteSelector.java:139) 
                                                     at okhttp3.internal.http.RouteSelector.next(RouteSelector.java:81) 
                                                     at okhttp3.internal.http.StreamAllocation.findConnection(StreamAllocation.java:172) 
                                                     at okhttp3.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:123) 
                                                     at okhttp3.internal.http.StreamAllocation.newStream(StreamAllocation.java:93) 
                                                     at okhttp3.internal.http.HttpEngine.connect(HttpEngine.java:296) 
                                                     at okhttp3.internal.http.HttpEngine.sendRequest(HttpEngine.java:248) 
                                                     at okhttp3.RealCall.getResponse(RealCall.java:243) 
                                                     at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:201) 
                                                     at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:163) 
                                                     at okhttp3.RealCall.access$100(RealCall.java:30) 
                                                     at okhttp3.RealCall$AsyncCall.execute(RealCall.java:127) 
                                                     at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32) 
                                                     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 
                                                     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
                                                     at java.lang.Thread.run(Thread.java:761) 
                                                  Caused by: android.system.ErrnoException: android_getaddrinfo failed: EACCES (Permission denied)
                                                     at libcore.io.Posix.android_getaddrinfo(Native Method) 
                                                     at libcore.io.ForwardingOs.android_getaddrinfo(ForwardingOs.java:55) 
                                                     at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:106) 
                                                     at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:74) 
                                                     at java.net.InetAddress.getAllByName(InetAddress.java:752) 
                                                     at okhttp3.Dns$1.lookup(Dns.java:39) 
                                                     at okhttp3.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:173) 
                                                     at okhttp3.internal.http.RouteSelector.nextProxy(RouteSelector.java:139) 
                                                     at okhttp3.internal.http.RouteSelector.next(RouteSelector.java:81) 
                                                     at okhttp3.internal.http.StreamAllocation.findConnection(StreamAllocation.java:172) 
                                                     at okhttp3.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:123) 
                                                     at okhttp3.internal.http.StreamAllocation.newStream(StreamAllocation.java:93) 
                                                     at okhttp3.internal.http.HttpEngine.connect(HttpEngine.java:296) 
                                                     at okhttp3.internal.http.HttpEngine.sendRequest(HttpEngine.java:248) 
                                                     at okhttp3.RealCall.getResponse(RealCall.java:243) 
                                                     at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:201) 
                                                     at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:163) 
                                                     at okhttp3.RealCall.access$100(RealCall.java:30) 
                                                     at okhttp3.RealCall$AsyncCall.execute(RealCall.java:127) 
                                                     at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32) 
                                                     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 
                                                     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
                                                     at java.lang.Thread.run(Thread.java:761) 

主要 Activity 代码:

package com.example.asus.weather;

import android.content.ClipData;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class MainActivity extends AppCompatActivity {

    ListView listView;
    ArrayList<ClipData.Item> myDataList = new ArrayList<>();
    ArrayList<String> myStringList = new ArrayList<>();
    DatabaseHandler db = new DatabaseHandler(this);
    private SOService mService;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listView = (ListView) findViewById(R.id.rv_answers);
        mService = ApiUtils.getSOService();

        loadAnswers();

        final ArrayList<String> myDataList = db.getAllWeather();

        if (myDataList.size() > 0)
            listView.setAdapter(new ArrayAdapter<String>(this, R.layout.list_item, R.id.label, myDataList));
    }

    public void loadAnswers() {
        mService.getAnswers().enqueue(new Callback<SOAnswerResponse>() {

            @Override
            public void onResponse(Call<SOAnswerResponse> call, Response<SOAnswerResponse> response) {
                if (response.isSuccessful()) {
                    List<Datum_> forcast = response.body().getDaily().getData();
                    db.addWeather(forcast);

                    Log.d("Session9", "Posts Loaded from API");
                } else {
                    int statusCode = response.code();
                    Toast.makeText(getApplicationContext(), response.message(), Toast.LENGTH_LONG).show();
                }
            }

            @Override
            public void onFailure(Call<SOAnswerResponse> call, Throwable t) {

            }
        });
    }
}

SOAnswerResponse 代码(API 数据):

package com.example.asus.weather;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class SOAnswerResponse {

    @SerializedName("latitude")
    @Expose
    private Double latitude;
    @SerializedName("longitude")
    @Expose
    private Double longitude;
    @SerializedName("timezone")
    @Expose
    private String timezone;
    @SerializedName("currently")
    @Expose
    private Currently currently;
    @SerializedName("hourly")
    @Expose
    private Hourly hourly;
    @SerializedName("daily")
    @Expose
    private Daily daily;
    @SerializedName("flags")
    @Expose
    private Flags flags;
    @SerializedName("offset")
    @Expose
    private Double offset;

    public Double getLatitude() {
        return latitude;
    }

    public void setLatitude(Double latitude) {
        this.latitude = latitude;
    }

    public Double getLongitude() {
        return longitude;
    }

    public void setLongitude(Double longitude) {
        this.longitude = longitude;
    }

    public String getTimezone() {
        return timezone;
    }

    public void setTimezone(String timezone) {
        this.timezone = timezone;
    }

    public Currently getCurrently() {
        return currently;
    }

    public void setCurrently(Currently currently) {
        this.currently = currently;
    }

    public Hourly getHourly() {
        return hourly;
    }

    public void setHourly(Hourly hourly) {
        this.hourly = hourly;
    }

    public Daily getDaily() {
        return daily;
    }

    public void setDaily(Daily daily) {
        this.daily = daily;
    }

    public Flags getFlags() {
        return flags;
    }

    public void setFlags(Flags flags) {
        this.flags = flags;
    }

    public Double getOffset() {
        return offset;
    }

    public void setOffset(Double offset) {
        this.offset = offset;
    }

}

改造客户端:

package com.example.asus.weather;

/**
 * Created by asus on 8/16/2018.
 */

import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class RetrofitClient {
    private static Retrofit retrofit = null;
    public static Retrofit getClient(String baseUrl){
        if(retrofit==null){
            retrofit = new Retrofit.Builder()
                    .baseUrl(baseUrl)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }
        return retrofit;
    }
}

SO服务:

package com.example.asus.weather;
/**
 * Created by asus on 8/16/2018.
 */
import retrofit2.Call;
import  retrofit2.http.GET;
import retrofit2.http.Query;

public interface SOService {
    @GET("/forecast/f981283055910310969577c70c37a302/35.69439,51.42151")
    Call<SOAnswerResponse> getAnswers();

    @GET("/forecast/f981283055910310969577c70c37a302/35.69439,51.42151")
    Call<SOAnswerResponse> getAnswers(@Query("tagged") String tags);
}

ApiUtils:

package com.example.asus.weather;

import retrofit2.Retrofit;

/**
 * Created by asus on 8/16/2018.
 */

public class ApiUtils {
    public static final String BASE_URL = "https://api.darksky.net";

    public static  SOService getSOService(){
        return RetrofitClient.getClient(BASE_URL).create(SOService.class);
    }
}

最佳答案

我不熟悉logcat。查看 logCat 后,我​​发现我没有在 list 中使用 Internet Permission。

关于android 模拟器在 Retrofit CallBack 中崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51901737/

相关文章:

Android 上的 C++ 命令行应用程序?

android - 获取 "No results"消息自定义适配器 ListView Android

php - 使用 Google 地理编码器/API 根据地址返回邻域

android - 使用 minSdkVersion 之外的 API 级别的属性

Swift:按顺序执行多个异步请求。如何等待上一个请求完成?

callback - D:委托(delegate)还是回调?

java - Android 中的 XML 架构验证

ruby-on-rails - 在 rails3 中使用观察者自定义回调

c++ - 将指向成员函数的指针作为指向函数的指针传递

android - Snackbar 在按下操作按钮时隐藏 float 操作