【问题标题】:Not getting my response when calling my api using MVVM and Retrofit?使用 MVVM 和 Retrofit 调用我的 api 时没有得到我的响应?
【发布时间】:2020-07-25 05:16:45
【问题描述】:

我正在尝试在我的应用程序中使用 MVVM、Retrofit、Dagger,所以在乞求时我只使用了一个 ArrayList 将我的数据从 viewModel 显示到 View 并且它有效,现在我正在使用它,但是我收到一个错误,我没有收到错误,我似乎不清楚。

我在本地机器上使用了一个返回 JSON 响应的 php 脚本。

我想我有很多代码要在这里提供,所以这是我的 ContractListViewModel :

public class ContractsListViewModel extends ViewModel {
    public MutableLiveData<List<ContractModel>> contractList = new MutableLiveData<List<ContractModel>>();
    MutableLiveData<Boolean> isLoading= new MutableLiveData<Boolean>();
    MutableLiveData<Boolean> error= new MutableLiveData<Boolean>();

    @Inject
    ContractService contractService;

    CompositeDisposable disposable = new CompositeDisposable();

    public ContractsListViewModel(){
        super();
        DaggerContractApiComponent.create().inject(this);
    }

    public void call(){
        fetchContracts();
    }

    public void fetchContracts(){

        isLoading.setValue(true);

        disposable.add(
                contractService.getContracts()
                        .subscribeOn(Schedulers.newThread())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribeWith(new DisposableSingleObserver<List<ContractModel>>() {

                            @Override
                            public void onSuccess(List<ContractModel> friendsModels) {
                                isLoading.setValue(false);
                                error.setValue(false);
                                contractList.setValue(friendsModels);
                            }

                            @Override
                            public void onError(Throwable e) {
                                error.setValue(true);
                                isLoading.setValue(false);
                                e.printStackTrace();
                            }
                        })
        );

    }

    @Override
    protected void onCleared(){
        super.onCleared();
        disposable.clear();
    }


}

这是我的 ContractService :

public class ContractService {

    public static ContractService instance;

    @Inject
    public ContractApi api;

    private ContractService(){
        DaggerContractApiComponent.create().inject(this);
    }

    public static ContractService getInstance(){
        if(instance == null){
            instance = new ContractService();
        }
        return instance;
    }

    public Single<List<ContractModel>> getContracts(){
        return api.getContractList();
    }
}

这是我的 ContratApiComponent(用于注入):

@Component(modules = { ApiModule.class})
public interface ContractApiComponent {

    public void inject(ContractService contractService);
    public void inject(ContractsListViewModel contractListViewModel);

}

这是我的ContractApi:

public interface ContractApi {

    @GET("contrats.php")
    Single<List<ContractModel>> getContractList();

}

这是我的 ApiModule:

@Module
public class ApiModule {

    public static String BASE_URL = "http://localhost/newconceptsphp/";

    @Provides
    public ContractApi provideContractApi(){
        return new Retrofit.Builder().baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build()
                .create(ContractApi.class);
    }

    @Provides
    public ContractService provideContractService(){
        return ContractService.getInstance();
    }

}

这是我的 MainActivity :

public class MainActivity extends AppCompatActivity {

    ContractsListViewModel contractsListViewModel;

    @BindView(R.id.newContractBtn)
    Button newContractBtn;

    RecyclerView.Adapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        ActivityMainBinding main = DataBindingUtil.setContentView(this, R.layout.activity_main);

        ButterKnife.bind(this);
        main.contractList.setLayoutManager(new LinearLayoutManager(this));

        contractsListViewModel = ViewModelProviders.of(this).get(ContractsListViewModel.class);
        contractsListViewModel.call();

        contractsListViewModel.contractList.observe(this,contractModels -> {
            if(contractModels != null){
            adapter = new ContractListAdapter(MainActivity.this, contractModels);
            main.contractList.setAdapter(adapter);
        }else {
            Log.d("TAG", "Nothing is here")
        }
        });

    }
}

我什么也得不到。

我期望得到的是:

这是我得到的:

这是我得到的错误:

2020-04-12 17:53:08.308 27128-27128/com.example.cosysimulation W/System.err: java.net.ConnectException: Failed to connect to localhost/127.0.0.1:80
2020-04-12 17:53:08.309 27128-27128/com.example.cosysimulation W/System.err:     at okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.java:225)
2020-04-12 17:53:08.309 27128-27128/com.example.cosysimulation W/System.err:     at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:149)
2020-04-12 17:53:08.310 27128-27128/com.example.cosysimulation W/System.err:     at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:192)

任何帮助都将不胜感激,因为我在一个项目中尝试过这个,然后我尝试制作一个新的,因为我认为我显然没有正确设置所有内容,但它似乎无法正常工作。

谢谢。

【问题讨论】:

  • 从错误看来,在您的 localhost 端口 80 上没有运行服务器,或者您的服务器在 80 以外的端口上运行,或者服务器没有运行。
  • 是的,我更正了,我将对我的问题进行编辑以显示答案。

标签: java android api mvvm retrofit


【解决方案1】:

所以我找到了解决问题的方法,我不能在我的 BASE url 中使用 localhost,我必须调用 IP 地址,原因是当你调用 localhost 时,它指的是 android 模拟器而不是 PC,因此,为了在您的本地 PC 机器中定位 api,请使用其 IP:

@Module
public class ApiModule {

public static String BASE_URL = "http://***IP ADRRSS HERE INSTEAD OF LOCALHOST***/newconceptsphp/";

@Provides
public ContractApi provideContractApi(){
    return new Retrofit.Builder().baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build()
            .create(ContractApi.class);
}

@Provides
public ContractService provideContractService(){
    return ContractService.getInstance();
}

}

【讨论】:

    【解决方案2】:

    尝试使用adb reverse tcp:80 tcp:80。这允许模拟器访问您的 PC(主机)上的端口 80

    【讨论】:

      猜你喜欢
      • 2018-02-05
      • 2023-02-23
      • 1970-01-01
      • 1970-01-01
      • 2019-09-03
      • 2019-04-12
      • 1970-01-01
      • 2019-12-16
      • 1970-01-01
      相关资源
      最近更新 更多