RepositoryClass
public Observable<Weather> requestWeather (String location,String unit,String appId){
return weatherAPI.requestWeather(location, unit,appId);
}
GetUseCase
public interface GetUseCase {
void execute(String location,String unit,String appId);
}
GetUseCaseImpl
public class GetUseCaseImpl implements GetUseCase {
private WeatherRepositorty weatherRepositorty;
private CompositeDisposable disposable = new CompositeDisposable();
private MutableLiveData<WeatherViewStated> mutableLiveData = new MutableLiveData<>();
public GetUseCaseImpl() {
weatherRepositorty = WeatherRepositorty.getInstance();
}
#Override
public void execute(String location, String unit, String appId) {
disposable.add(weatherRepositorty.requestWeather(location, unit, appId).subscribeOn(Schedulers.io()).doOnSubscribe((newsList) -> onLoading())
.subscribe(this::onSuccess,
this::onError));
}
private void onSuccess(Weather weather) {
WeatherViewStated.SUCCESS_STATE.setData(weather);
mutableLiveData.postValue(WeatherViewStated.SUCCESS_STATE);
}
private void onError(Throwable error) {
WeatherViewStated.ERROR_STATE.setError(error);
mutableLiveData.postValue(WeatherViewStated.ERROR_STATE);
}
private void onLoading() {
mutableLiveData.postValue(WeatherViewStated.LOADING_STATE);
}
}
WeatherViewStated
public class WeatherViewStated extends WeatherViewState<Weather> {
private WeatherViewStated(Weather data, int currentState, Throwable error) {
this.data = data;
this.error = error;
this.currentState = currentState;
}
public static WeatherViewStated ERROR_STATE = new WeatherViewStated(null, WeatherViewState.State.FAILED.value, new Throwable());
public static WeatherViewStated LOADING_STATE = new WeatherViewStated(null, State.LOADING.value, null);
public static WeatherViewStated SUCCESS_STATE = new WeatherViewStated(new Weather(), State.SUCCESS.value, null);
}
WeatherViewModel
public class WeatherViewModel extends ViewModel {
private MutableLiveData<Weather> mutableWeatherLiveData;
private WeatherRepositorty weatherRepositorty;
public void init(String location,String unit,String appID) {
}
}
This is my code i am trying to write code using mvvm clean architecture but i am unable to add code in GetUseCase and GetUseCaseImpl so that i can get MutableLiveDta success and failure state in viewmodel class so that i can use it in MainActvitiy please suggest me how to call and how to get data in View Model .
Change UseCase
public interface GetUseCase {
void execute(String location,String unit,String appId);
}
To
public interface GetUseCase {
Observable<Weather> execute(String location,String unit,String appId);
}
GetUseCaseImpl To
public class GetUseCaseImpl implements GetUseCase {
private WeatherRepositorty weatherRepositorty;
public GetUseCaseImpl() {
weatherRepositorty = WeatherRepositorty.getInstance();
}
#Override
public Observable<Weather> execute(String location, String unit, String appId) {
return weatherRepositorty.requestWeather(location, unit, appId)
}
}
ViewModel
public class WeatherViewModel extends ViewModel {
private CompositeDisposable disposable = new CompositeDisposable();
private MutableLiveData<WeatherViewStated> mutableLiveData = new
MutableLiveData<>();
private GetUseCaseImpl useCaseImpl = new GetUseCaseImpl()
public void init(String location,String unit,String appID) {
disposable.add(useCaseImpl.execute(location, unit, appId).subscribeOn(Schedulers.io()).doOnSubscribe((newsList) -> onLoading())
.subscribe(this::onSuccess,
this::onError));
}
private void onSuccess(Weather weather) {
WeatherViewStated.SUCCESS_STATE.setData(weather);
mutableLiveData.postValue(WeatherViewStated.SUCCESS_STATE);
}
private void onError(Throwable error) {
WeatherViewStated.ERROR_STATE.setError(error);
mutableLiveData.postValue(WeatherViewStated.ERROR_STATE);
}
private void onLoading() {
mutableLiveData.postValue(WeatherViewStated.LOADING_STATE);
}
override fun onCleared() {
disposable.clear()
}
}
Related
I want to post this object
public class EditTask {
#SerializedName("id")
private int id;
#SerializedName("active")
private int active;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getActive() {
return active;
}
public void setActive(int active) {
this.active = active;
}
public EditTask(int id, int active) {
this.id = id;
this.active = active;
}
}
My api:
public interface TaskApi {
#GET("func.php?load")
Call<List<Task» getTaskList();
#FormUrlEncoded
#POST("func.php?add")
Call<String> addTask(#Field("name") String name);
#POST("func.php?edit")
Call<EditTask> editTask(#Body EditTask editTask);
}
My Repositary:
public class TaskRepository {
private static TaskRepository taskRepository;
public static TaskRepository getInstance() {
if (taskRepository == null) {
taskRepository = new TaskRepository();
}
return taskRepository;
}
private TaskApi taskApi;
public TaskRepository() {
taskApi = RetrofitService.createService(TaskApi.class);
}
public void editTask(int id, int active) {
EditTask editTask = new EditTask(id, active);
taskApi.editTask(editTask).enqueue(new Callback<EditTask>() {
#Override
public void onResponse(Call<EditTask> call, Response<EditTask> response) {
Log.i("Artemy", "cool");
}
#Override
public void onFailure(Call<EditTask> all, Throwable t) {
Log.i("Artemy", "notcool");
}
});
}
}
My RetrofitService:
public class RetrofitService {
private static Gson gson = new GsonBuilder()
.setLenient()
.create();
private static Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://loginov.tech/android/")
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
public static <S> S createService(Class<S> serviceClass) {
return retrofit.create(serviceClass);
}
}
My ViewModel:
public class TaskViewModel extends ViewModel {
private MutableLiveData<List<Task»mutableLiveData;
private TaskRepository taskRepository;
public void init() {
if (mutableLiveData != null) {
return;
}
taskRepository = TaskRepository.getInstance();
mutableLiveData = taskRepository.getTasks();
}
public LiveData<List<Task»
getTaskRepository() {
return mutableLiveData;
}
public void addTask(String name) {
taskRepository.addTask(name);
}
public void editTask(int id, int active) {
taskRepository.editTask(id, active);
}
}
Main Activity:
public class TaskViewModel extends ViewModel {
private MutableLiveData<List<Task»mutableLiveData;
private TaskRepository taskRepository;
public void init() {
if (mutableLiveData != null) {
return;
}
taskRepository = TaskRepository.getInstance();
mutableLiveData = taskRepository.getTasks();
}
public LiveData<List<Task»
getTaskRepository() {
return mutableLiveData;
}
public void addTask(String name) {
taskRepository.addTask(name);
}
public void editTask(int id, int active) {
taskRepository.editTask(id, active);
}
}
I must create post request to server and post int id and int active parameters.But i always get error :java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 2 column 1 path
I tried to post List of EditTasks also i tried to make post with #FormUrlEncoded it did not help.
Trying to learn Room and RXJAVA.
I have about 80% of this understood but I'm getting stuck on figuring the rest out.
Here is the error I get on the insert data.
java.lang.NullPointerException: Attempt to invoke interface method
'void
com.example.learnroom.EntityDao.insert(com.example.learnroom.Entitys)'
on a null object reference
If I don't run the try catch I get the following error which seems to be related.
java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.example.learnroom/com.example.learnroom.MainActivity}:
java.lang.NullPointerException: Attempt to invoke interface method
'io.reactivex.Maybe
com.example.learnroom.EntityDao.getEntity(java.lang.String)' on a null
object reference
How do I fix this?
I have tried to simplify from the tutorials all over the web most using recyclerviews to just 2 text fields. They say this is 3 pieces but it doesn't seem like it, as the DB was never set up so I ran it in a method to run the code. Maybe someone can help explain to me how this really works.
my code
Dao
public interface EntityDao {
#Query("SELECT * FROM Entitys WHERE ID = :ID LIMIT 1")
Maybe<List<Entitys>> getEntity(String ID);
#Insert(onConflict = OnConflictStrategy.REPLACE)
void insert(Entitys entitys);
#Query("DELETE FROM Entitys")
void deleteAllEntity();
}
Entity
public class Entitys {
#PrimaryKey
#NonNull
public String ID;
public String ts;
public String tss;
public Entitys(#NonNull String ID, String ts, String tss) {
this.ID = ID;
this.ts = ts;
this.tss = tss;
}
public String getTss() {
return tss;
}
public void setTss(String tss) {
this.tss = tss;
}
public void setID(String ID) {
this.ID = ID;
}
public void setTs(String ts) {
this.ts = ts;
}
public String getID() {
return ID;
}
public String getTs() {
return ts;
}
}
database
#Database(entities = {Entitys.class}, version = 1)
public abstract class PathwaysDB extends RoomDatabase {
private static volatile PathwaysDB INSTANCE;
public static EntityDao entityDao() {
return null;
}
public static PathwaysDB getInstance(Context context) {
if (INSTANCE == null) {
synchronized (PathwaysDB.class) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
PathwaysDB.class, "Pathwaysdb")
.build();
}
}
}
return INSTANCE;
}
}
MainActivity
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = MainActivity.class.getSimpleName();
Button tb;
EditText te, tes;
String ts, tss, ID;
CompositeDisposable compositeDisposable = new CompositeDisposable();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ID ="test";
te = findViewById(R.id.te);
tb = findViewById(R.id.tb);
tb.setOnClickListener(this);
tes = findViewById(R.id.tes);
Builddb();
try{
getData();}catch (Exception e){}
}
private void Builddb() {
Completable.fromAction(() -> PathwaysDB.getInstance(this))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new CompletableObserver() {
#Override
public void onSubscribe(Disposable d) {
compositeDisposable.add(d);
}
#Override
public void onComplete() {
// action was completed successfully
}
#Override
public void onError(Throwable e) {
// something went wrong
}
});
}
private void getData() {
Maybe<List<Entitys>> single = entityDao().getEntity(ID);
single.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new MaybeObserver<List<Entitys>>() {
#Override
public void onSubscribe(Disposable d) {
// add it to a CompositeDisposable
}
#Override
public void onSuccess(List<Entitys> entity) {
te.setText(entity.indexOf(ts));
tes.setText(entity.indexOf(tss));
}
#Override
public void onError(Throwable e) {
// show an error message
}
#Override
public void onComplete() {
}
});
compositeDisposable.add((Disposable) single);
}
#Override
protected void onDestroy() {
super.onDestroy();
compositeDisposable.dispose();
}
private void updateUserName() {
ts = te.getText().toString();
tss = tes.getText().toString();
Entitys entitys = new Entitys(ID, ts, tss);
Completable.fromAction(() -> entityDao().insert(entitys))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new CompletableObserver() {
#Override
public void onSubscribe(Disposable d) {
compositeDisposable.add(d);
}
#Override
public void onComplete() {
// action was completed successfully
}
#Override
public void onError(Throwable e) {
// something went wrong
}
});
}
#Override
public void onClick(View view) {
updateUserName();
Intent forward = new Intent(this, secondpage.class);
startActivity(forward);
}
}
Reason for crash is this line in your PathwaysDB class
public static EntityDao entityDao() {
return null;
}
it is returning null. It should be like
public abstract EntityDao entityDao()
You forget to add #Dao annonation to your EntityDao interface class.
also you need to change below method :
public static EntityDao entityDao() {
return null;
}
To
public abstract EntityDao entityDao();
I am writing an Android application which runs a series of back-up works.
I use workmanager to do this in the background.
Now how do I implement WorkManager in MVP ?
Below is the module for workers
#Module
public class WorkerModule {
private final Worker mworker;
public WorkerModule(Worker worker) {
mworker = worker;
}
#Provides
CompositeDisposable provideCompositeDisposable() {
return new CompositeDisposable();
}
#Provides
SchedulerProvider provideSchedulerProvider() {
return new AppSchedulerProvider();
}
////////////Presenter
}
Below is my component for Workers
#PerWorker
#Component(dependencies = ApplicationComponent.class, modules = `WorkerModule.class)
public interface WorkerComponent {
void inject(sendLocationWorker worker);
}`
Below is my Presenter
public class LocationRequestPresenter<V extends MainMvpView> extends BasePresenter<V>
implements LocationRequestMvpPresenter<V> {
private static final String TAG = "LocationRequestPresenter";
private boolean ischecked = false;
#Inject
public LocationRequestPresenter(DataManager dataManager,
SchedulerProvider schedulerProvider,
CompositeDisposable compositeDisposable) {
super(dataManager, schedulerProvider, compositeDisposable);
}
#Override
public void onGetLocations() {
getCompositeDisposable().add(getDataManager().getAllLocations()
.subscribeOn(getSchedulerProvider().io())emphasized text
.observeOn(getSchedulerProvider().ui())
.subscribe(new Consumer<List<Location>>() {
#Override
public void accept(List<Location> locationList) throws Exception {
onSendLocations(locationList);
}
}
, new Consumer<Throwable>() {
#Override
public void accept(Throwable throwable) throws Exception {
}
}));
}
#Override
public void onSendLocations(List<Location> locationList) {
getCompositeDisposable().add(getDataManager().doSendLocationHistory(new AddLocationRequest(locationList))
.subscribeOn(getSchedulerProvider().io())
.observeOn(getSchedulerProvider().ui())
.subscribe(new Consumer<CommonResponse>() {
#Override
public void accept(CommonResponse s) throws Exception {
ischecked = false;
}
}, new Consumer<Throwable>() {
#Override
public void accept(Throwable throwable) throws Exception {
}
}));
}
}
Now, why when I use Presenter, the worker returns null for presenter
for injecting Presenter I use this on my worker:
RequestPresenter<MainMvpView> mPresenter;
I'm new in android architecture component. this is my code , i'm at the point that I don't know how to notify my activity and get the results back
these are my codes:
Activity:
private void iniViewModels() {
Observer<List<User>>usersObserver=new Observer<List<User>>() {
#Override
public void onChanged(#Nullable List<User> users) {
Log.v("this","LiveData: ");
for (int i=0;i<users.size();i++){
Log.v("this",users.get(i).getName());
}
}
};
mViewModel = ViewModelProviders.of(this)//of-->name of act or fragment
.get(AcActivityViewModel.class);///get -->the name of viewModelClass
mViewModel.mUsers.observe(this,usersObserver);
}
this is my viewModel Class:
public class IpStaticViewModel extends AndroidViewModel {
public LiveData<List<Ipe>> ips;
private AppRepository repository;
public IpStaticViewModel(#NonNull Application application) {
super(application);
repository=AppRepository.getInstance(application.getApplicationContext());
}
public void getIpStatics() {
repository.getStaticIps();
}
}
this is my repository class:
public class AppRepository {
private static AppRepository ourInstance ;
private Context context;
private IpStaticInterface ipInterface;
public static AppRepository getInstance(Context context) {
if (ourInstance == null) {
ourInstance=new AppRepository(context);
}
return ourInstance;
}
private AppRepository(Context context) {
this.context=context;
}
public void getStaticIps() {
ipInterface= ApiConnection.getClient().create(IpStaticInterface.class);
ipInterface.getIpes()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new SingleObserver<IpStaticList>() {
#Override
public void onSubscribe(Disposable d) {
}
#Override
public void onSuccess(IpStaticList ipStaticList) {
List<Ipe>ips=ipStaticList.getIpes();
}
#Override
public void onError(Throwable e) {
Log.v("this","Eror "+ e.getMessage());
}
});
}
}
I'm using retrofit for fetching the data ,it fetch the data successfully but I don't know how to notify my activity
can you help me?
Have a MutableLiveData
final MutableLiveData<List<Ipe>> data = new MutableLiveData<>();
In onSucess
public MutableLiveData<List<Ipe>> getStaticIps() {
ipInterface= ApiConnection.getClient().create(IpStaticInterface.class);
ipInterface.getIpes()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new SingleObserver<IpStaticList>() {
#Override
public void onSubscribe(Disposable d) {
}
#Override
public void onSuccess(IpStaticList ipStaticList) {
List<Ipe>ips=ipStaticList.getIpes();
data.setValue(ips);
}
#Override
public void onError(Throwable e) {
Log.v("this","Eror "+ e.getMessage());
}
});
return data;
}
In repository expose this to viewmodel
public LiveData<List<Ipe>> getIpStatics() {
return repository.getStaticIps();
}
In Activity you observe the livedata
IpStaticViewModel viewmodel = ViewModelProviders.of(this
.get(IpStaticViewModel.class)
viewModel.getIpStatics().observe(this, new Observer<List<Ipe>>() {
#Override
public void onChanged(#Nullable List<Ipe> ipes) {
if (ipes != null) {
// dosomething
}
}
});
If you want to generalize your response in case you have a error or something have a look at https://github.com/googlesamples/android-architecture-components/blob/master/GithubBrowserSample/app/src/main/java/com/android/example/github/vo/Resource.kt
I can make DI from some class to use in application such as Retrofit, Picasso.
they can work fine when i use them on Activity but when i try to use some DI on other class i get NULL, for exmple this code work fine
public class ActivityRegister extends BaseActivities {
#Inject
GithubService githubService;
#Inject
JobManager jobManager;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
...
repositoryCall = githubService.getAllRepositories();
...
}
private void getRepositories() {
repositoryCall.enqueue(new Callback<List<GithubRepo>>() {
#Override
public void onResponse(Call<List<GithubRepo>> call, Response<List<GithubRepo>> response) {
List<GithubRepo> repoList = new ArrayList<>();
repoList.addAll(response.body());
Log.e("JOB ", "OK");
}
#Override
public void onFailure(Call<List<GithubRepo>> call, Throwable t) {
Log.e("JOB ", "NO!!");
}
});
}
for GithubService i get created instance successfull, not i'm trying to use that into GetLatestRepositories, but i get NULL, how can i define correctly that to injecting into class?
public class GetLatestRepositories extends Job {
#Inject
GithubService githubService;
private Call<List<GithubRepo>> repositoryCall;
public GetLatestRepositories() {
super(new Params(Priority.MID).requireNetwork().persist());
repositoryCall = githubService.getAllRepositories();
}
#Override
public void onAdded() {
}
#Override
public void onRun() throws Throwable {
repositoryCall.enqueue(new Callback<List<GithubRepo>>() {
#Override
public void onResponse(Call<List<GithubRepo>> call, Response<List<GithubRepo>> response) {
List<GithubRepo> repoList = new ArrayList<>();
repoList.addAll(response.body());
Log.e("JOB ", "OK");
}
#Override
public void onFailure(Call<List<GithubRepo>> call, Throwable t) {
Log.e("JOB ", "NO!!");
}
});
}
#Override
protected void onCancel(int cancelReason, #Nullable Throwable throwable) {
}
#Override
protected RetryConstraint shouldReRunOnThrowable(#NonNull Throwable throwable, int runCount, int maxRunCount) {
return null;
}
}
ActivityRegisterComponent component class:
#ActivityRegisterScope
#Component(modules = ActivityRegisterModule.class, dependencies = GithubApplicationComponent.class)
public interface ActivityRegisterComponent {
void injectActivityRegister(ActivityRegister homeActivity);
}
GithubApplicationComponent:
#GithubApplicationScope
#Component(modules = {GithubServiceModule.class, PicassoModule.class, JobManagerModule.class, ActivityModule.class})
public interface GithubApplicationComponent {
Picasso getPicasso();
GithubService getGithubService();
JobManager getJobManager();
}
Application class:
public class Alachiq extends Application {
...
public static Alachiq alachiq;
public static String packageName;
public static Resources resources;
private static Context context;
private GithubService githubService;
private Picasso picasso;
private GithubApplicationComponent component;
private JobManager jobManager;
private static Alachiq instance;
#Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
}
#Override
public void onCreate() {
super.onCreate();
//#formatter:off
resources = this.getResources();
context = getApplicationContext();
packageName = getPackageName();
//#formatter:on
Timber.plant(new Timber.DebugTree());
component = DaggerGithubApplicationComponent.builder()
.contextModule(new ContextModule(this))
.build();
githubService = component.getGithubService();
picasso = component.getPicasso();
jobManager = component.getJobManager();
}
public GithubApplicationComponent component() {
return component;
}
public static Alachiq get(Activity activity) {
return (Alachiq) activity.getApplication();
}
public static Alachiq getInstance() {
return instance;
}
public static Context getContext() {
return context;
}
}
and ActivityRegister onCreate:
ApplicationComponent component = DaggerApplicationComponent.builder()
.githubApplicationComponent(Alachiq.get(this).component())
.build();
GithubService class:
public interface GithubService {
#GET("users/{username}/repos")
Call<List<GithubRepo>> getReposForUser(#Path("username") String username);
#GET("repositories")
Call<List<GithubRepo>> getAllRepositories();
#GET("users/{username}")
Call<GithubUser> getUser(#Path("username") String username);
}
Before you can even use the object from GithubService class you need to do the following:
myComponent= DaggerMyComponent.builder().computerModule(new ComputerModule()).build();//replace accordingly.
In your case you will have to do something like:
githubService = DaggerGithubApplicationComponent.builder().nameofYourModule(new NameOfTheClass()).build);
Now you can use the githubService object:
repositoryCall = githubService.getAllRepositories();
This is a type of design pattern called creational.