Reputation: 1315
I am trying to use MVVM, Retrofit, Dagger in my application, So in the begging I was only using a an ArrayList to display my data from the viewModel to the View and it worked, Now I am using it all, but I am getting an error, I don't get the error, does not seem clear to me.
I am using a php script that returns a JSON response, in my local machine.
I have a lot of code to provide here I think, so here is my 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();
}
}
Here is my 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();
}
}
This my ContratApiComponent ( for injection ) :
@Component(modules = { ApiModule.class})
public interface ContractApiComponent {
public void inject(ContractService contractService);
public void inject(ContractsListViewModel contractListViewModel);
}
This is my ContratctApi :
public interface ContractApi {
@GET("contrats.php")
Single<List<ContractModel>> getContractList();
}
This is my 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();
}
}
This is my 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")
}
});
}
}
I am getting nothing.
What I expect to get is this :
Here is what I get :
This an error I get :
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)
Any help would be much appreciated, because I tried this in a project, then I tried to make a new one because I thought I did not set up everything right obviously but it seems like it is not working.
Thank you.
Upvotes: 0
Views: 586
Reputation: 1315
So i found a solution to my problem, I had to not use a localhost in my BASE url, I had to call the IP adress, The reason is when you call localhost, it refers to the android emulator and not PC, so in order to target the api in your local pc machine, use its 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();
}
}
Upvotes: 0
Reputation: 1698
Try using adb reverse tcp:80 tcp:80
. This allows the emulator to access port 80 on your PC (host)
Upvotes: 2