How to parse JSON using Retrofit correctly and implement it in RecyclerView? - mvvm

I'm trying to build an app that has 2 tabs that displays Movies and TV Shows using the themoviedb.org API. It's supposed to use the MVVM model and i'm really confuse because it's just been 2 months since i started coding in Android. How to pass it correctly through each class and do i using the retrofit method correctly in the repository class?
The idea is accessing the API through Repository class and pass the data to the ViewModel class, and then display it in MovieFragment using RecyclerView, but it seems i failed to pass the data through each class.
+MovieRepository Class
public class MovieRepository {
private static MovieRepository instance;
private static ArrayList<Movie> movies = new ArrayList<>();
private final String API_KEY = "81d8f4353c2ade529071133972205017";
private String language;
private final String TAG = "repo";
public static MovieRepository getInstance() {
if (instance == null) {
instance = new MovieRepository();
}
return instance;
}
public static ArrayList<Movie> getMovies() {
return movies;
}
public MovieRepository() {
final ArrayList<Movie> movieJSON = new ArrayList<>();
language = "en_US";
ApiConfig api = new ApiConfig();
api.createInstance().loadMovieData(API_KEY, language).enqueue(new Callback<JSONResponse>() {
#Override
public void onResponse(Call<JSONResponse> call, Response<JSONResponse> response) {
ArrayList<Movie> jsonResults = response.body().getResults();
for (int i = 0; i < jsonResults.size() ; i++){
Movie movie = new Movie();
movie.setId(jsonResults.get(i).getId());
movie.setTitle(jsonResults.get(i).getTitle());
movie.setOverview(jsonResults.get(i).getOverview());
movie.setReleaseDate(jsonResults.get(i).getReleaseDate());
movie.setPosterPath(jsonResults.get(i).getPosterPath());
movieJSON.add(movie);
}
Log.d(TAG, "onResponse: " + jsonResults.toString());
}
#Override
public void onFailure(Call<JSONResponse> call, Throwable t) {
Log.d(TAG, "onFailure: " + t.getMessage());
}
});
this.movies = movieJSON;
}
+MovieViewModel Class
public class MovieViewModel extends ViewModel {
private static MutableLiveData<ArrayList<Movie>> movieData = new MutableLiveData<>();
private static ArrayList<Movie> movies;
public static LiveData<ArrayList<Movie>> getMoviesData() {
return movieData;
}
public static MovieAdapter init(MovieAdapter adapter) {
if (movies == null) {
movies = MovieRepository.getInstance().getMovies();
adapter.setMovies(movies);
}
return adapter;
}
+MovieFragment Class
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
movieViewModel = ViewModelProviders.of(this).get(MovieViewModel.class);
adapter = new MovieAdapter(getContext());
movieViewModel.init(adapter);
movieViewModel.getMoviesData().observe(this, new Observer<ArrayList<Movie>>() {
#Override
public void onChanged(#Nullable ArrayList<Movie> movies) {
adapter.notifyDataSetChanged();
}
});
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_movie_list, container, false);
if (view instanceof RecyclerView) {
final Context context = view.getContext();
RecyclerView recyclerView = (RecyclerView) view;
recyclerView.setLayoutManager(new LinearLayoutManager(context));
recyclerView.setAdapter(adapter);
}
return view;
}
it always ends up NullPointer in the Adapter (probably because the data failed to be passed to adapter)

Related

problem with Nested recyclerview and LiveData observe

I have nested RecyclerView and two LiveData. one is parentList and another one is childList
I managed to use LiveData for ParentAdapter but when I try LiveData for ChildAdapter nothing showen in childAdapter. ParentAdapter is working.
Can someone help me?
Thanks?
this method is in MainActivity.class
private void sendAllDataToAdapter(){
CashFlowViewModel viewModel = ViewModelProviders.of(this).get(CashFlowViewModel.class);
viewModel.cashGroupByDate().observe(this, new Observer<List<CashFlow>>() {
#Override
public void onChanged(List<CashFlow> cashFlows) {
adapter.submitList(cashFlows);
}
});
adapter = new MainAdapter(this, this);
recyclerView.setAdapter(adapter);
}
This is ParentAdapter
public class MainAdapter extends ListAdapter<CashFlow, MainAdapter.MainViewHolder>{
Context context;
List<CashFlow> cashFlowList = new ArrayList<>();
List<CashFlow> cashFlowListChild = new ArrayList<>();
CashflowRepository repository;
CashFlowViewModel viewModel;
LifecycleOwner lifecycleOwner;
public MainAdapter(Context context, LifecycleOwner lifecycleOwner) {
super(diffCallback);
this.context = context;
this.cashFlowList = cashFlowList;
this.cashFlowListChild = cashFlowListChild;
this.repository = repository;
this.lifecycleOwner = lifecycleOwner;
viewModel = ViewModelProviders.of((MainActivity) context).get(CashFlowViewModel.class);
}
private static final DiffUtil.ItemCallback<CashFlow> diffCallback = new DiffUtil.ItemCallback<CashFlow>() {
#Override
public boolean areItemsTheSame(#NonNull CashFlow oldItem, #NonNull CashFlow newItem) {
return oldItem.getId() == newItem.getId();
}
#Override
public boolean areContentsTheSame(#NonNull CashFlow oldItem, #NonNull CashFlow newItem) {
return oldItem.getAdded_date().equals(newItem.getAdded_date())
&& oldItem.getTitle().equals(newItem.getTitle())
&& oldItem.getBody().equals(newItem.getBody());
}
};
#NonNull
#Override
public MainViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.main_adapter, parent, false);
return new MainViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MainViewHolder holder, int position) {
holder.tvDate.setText(getItem(position).getAdded_date());
holder.tvIncome.setText(String.valueOf(getItem(position).getIncome()));
holder.tvExpense.setText(String.valueOf(getItem(position).getExpense()));
ChildAdapter adapter = new ChildAdapter(context);
holder.rvChild.setAdapter(adapter);
viewModel.cashGroupByDate().observe(lifecycleOwner, new Observer<List<CashFlow>>() {
#Override
public void onChanged(List<CashFlow> cashFlows) {
adapter.submitList(cashFlows);
}
});
Log.d("Child", getItem(position).getAdded_date()+"");
}
public class MainViewHolder extends RecyclerView.ViewHolder {
TextView tvDate, tvIncome, tvExpense;
RecyclerView rvChild;
public MainViewHolder(#NonNull View itemView) {
super(itemView);
tvDate = itemView.findViewById(R.id.main_adapter_date);
tvIncome = itemView.findViewById(R.id.main_adapter_income);
tvExpense = itemView.findViewById(R.id.main_adapter_expense);
rvChild = itemView.findViewById(R.id.child_recyclerview);
}
}
This is ChildAdapter
public class ChildAdapter extends ListAdapter<CashFlow, ChildAdapter.ChildViewHolder> {
Context context;
public ChildAdapter(Context context) {
super(diffCallback);
this.context = context;
}
private static final DiffUtil.ItemCallback<CashFlow> diffCallback = new DiffUtil.ItemCallback<CashFlow>() {
#Override
public boolean areItemsTheSame(#NonNull CashFlow oldItem, #NonNull CashFlow newItem) {
return oldItem.getId() == newItem.getId();
}
#Override
public boolean areContentsTheSame(#NonNull CashFlow oldItem, #NonNull CashFlow newItem) {
return oldItem.getAdded_date().equals(newItem.getAdded_date())
&& oldItem.getBody().equals(newItem.getBody())
&& oldItem.getTitle().equals(newItem.getTitle())
&& oldItem.getExpense() == newItem.getExpense()
&& oldItem.getIncome() == newItem.getIncome()
&& oldItem.getType().equals(newItem.getType());
}
};
#NonNull
#Override
public ChildViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.child_adapter, parent, false);
return new ChildViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ChildViewHolder holder, int position) {
holder.imageView.setImageResource(getItem(position).getImage_id());
holder.tvTitle.setText(getItem(position).getTitle());
if (getItem(position).getType().equals(BaseActivity.INCOME)){
holder.tvSum.setText(String.valueOf(getItem(position).getIncome()));
}
else if (getItem(position).getType().equals(BaseActivity.EXPENSE)){
holder.tvSum.setText(String.valueOf(getItem(position).getExpense()));
}
}
public class ChildViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
TextView tvTitle, tvSum;
public ChildViewHolder(#NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.child_adapter_image);
tvTitle = itemView.findViewById(R.id.child_adapter_title);
tvSum = itemView.findViewById(R.id.child_adapter_sum);
}
}
}
This is my ViewModel.class
public class CashFlowViewModel extends AndroidViewModel {
private CashflowRepository repository;
public CashFlowViewModel(#NonNull Application application) {
super(application);
repository = new CashflowRepository(application);
}
public void insert(CashFlow cashFlow){
repository.insert(cashFlow);
}
public void update(CashFlow cashFlow){
repository.update(cashFlow);
}
public void delete(CashFlow cashFlow){
repository.delete(cashFlow);
}
public LiveData<List<CashFlow>> cashGroupByDate(){
return repository.getCashGroupByDate();
}
public LiveData<List<CashFlow>> cashByDate(String addedDate){
return repository.getCashByDate(addedDate);
}
public void insertCategory(Category category){
repository.insertCategory(category);
}
public void updateCategory(Category category){
repository.updateCategory(category);
}
public void deleteCategory(Category category){
repository.deleteCategory(category);
}
public List<Category> allCategories(String type){
return repository.getAllCategories(type);
}

How to convert Firebase child name into date and time

I have a basic app that has RecyclerView for getting data from a Firebase database, which looks like this:
I would like to have the 20170108_100 converted into data and time format (08/01/2017 10:00), which can then be compared to the actual date.
I'm planning to have some IF conditions in order to sort the database by date&time and I need to have something like this:
if (20170108_100 < CurrentDate&Time) then doSomething else doSomethingElse
Is there any way one can do that?
So far, I have this code that reads that database:
public class Hotarari extends Fragment {
View v;
ProgressDialog progress;
private FirebaseRecyclerAdapter < Variabile_primarie, ContactViewHolder > cc;
private RecyclerView mContactRV;
private DatabaseReference mPostRef;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
v = inflater.inflate(R.layout.fragment_hotarari, container, false);
return v;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
this.v = view;
initialiseScreen();
}
private void initialiseScreen() {
mContactRV = (RecyclerView) v.findViewById(R.id.contact_recyclerview);
mContactRV.setLayoutManager(new LinearLayoutManager(getContext()));
mPostRef = FirebaseDatabase.getInstance().getReference("-DeciziiPrimari");
setupAdaptater();
mContactRV.setAdapter(cc);
}
private void setupAdaptater() {
cc = new FirebaseRecyclerAdapter < Variabile_primarie, ContactViewHolder > (
Variabile_primarie.class,
R.layout.item_hotarari,
ContactViewHolder.class,
mPostRef
) {
#Override
protected void populateViewHolder(ContactViewHolder viewHolder, final Variabile_primarie model, int position) {
viewHolder.setData(model.getData());
viewHolder.setNumar(model.getNumar());
viewHolder.setHotarare(model.getHotarare());
}
};
}
public static class ContactViewHolder extends RecyclerView.ViewHolder {
private TextView tv_hotarare;
private TextView tv_data;
private TextView tv_numar;
public ContactViewHolder(View itemView) {
super(itemView);
tv_hotarare = (TextView) itemView.findViewById(R.id.continut_hotarare);
tv_data = (TextView) itemView.findViewById(R.id.data_hotarare);
tv_numar = (TextView) itemView.findViewById(R.id.numar_hotarare);
}
void setHotarare(String hotarare) {
tv_hotarare.setText(String.valueOf(hotarare));
}
public void setData(String data) {
tv_data.setText(String.valueOf(data));
}
void setNumar(String numar) {
tv_numar.setText(String.valueOf(numar));
}
}
}

How to add timestamp for CardView

I am using FirebaseRecyclerAdapter my issue or problem is that I need to show timestamp for my posts card so I have searched for 3 months and I couldn't solve this problem so please brother I have done my best and it's time for getting help from others be in mind that I don't have any idea about timestamp ...
here's an example for how I want to show : 3 hours ago, 1 day, just now.
If some one solve me this problem by adding the solve for my JAVA fragment I will be proud for him.
Here's my fragment
public class Challenges extends Fragment{
private RecyclerView mPostList;
private DatabaseReference mDatabase,mDatabaseFriends,mDatabaseLike;
private SwipeRefreshLayout mRefreshLayout;
private boolean mProcessLike = false;
private String AA;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mListener;
private Query mQuery;
private FirebaseUser mCurrentUser;
public Challenges() {}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MultiDex.install(getActivity());}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v= inflater.inflate(R.layout.challenges, container, false);
mListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
final FirebaseUser User = firebaseAuth.getCurrentUser();
if (User == null) {
Intent A = new Intent(getActivity(), Login.class);
startActivity(A);}}};
mPostList=(RecyclerView)v.findViewById(R.id.PostList);
mPostList.setHasFixedSize(true);
mPostList.setItemAnimator(new DefaultItemAnimator());
mPostList.setLayoutManager(new LinearLayoutManager(getActivity()));
//Firebase
mDatabase= FirebaseDatabase.getInstance().getReference().child("Posts");
mDatabaseFriends= FirebaseDatabase.getInstance().getReference().child("Friends");
mDatabaseLike = FirebaseDatabase.getInstance().getReference().child("Likes");
mDatabase.keepSynced(true);
mDatabaseLike.keepSynced(true);
mAuth = FirebaseAuth.getInstance();
mCurrentUser = mAuth.getCurrentUser();
mRefreshLayout=(SwipeRefreshLayout)v.findViewById(R.id.RefreshLayout);
//mQuery = mDatabase.orderByChild("UID").equalTo(String.valueOf(mDatabaseFriends.child(mCurrentUser.getUid()).child("Accepted")));
mRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
onStart();}});
return v;}
#Override
public void onStart() {
super.onStart();
mAuth.addAuthStateListener(mListener);
mRefreshLayout.setRefreshing(true);
final FirebaseRecyclerAdapter<Getting_Posts, PostViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Getting_Posts, PostViewHolder>(
Getting_Posts.class, R.layout.post_card_design, PostViewHolder.class, mDatabase) {
#SuppressLint("SetTextI18n")
#Override
protected void populateViewHolder(final PostViewHolder viewHolder, final Getting_Posts model, int position) {
final String Post_Key = getRef(position).getKey();
viewHolder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent A = new Intent(getActivity(), com.pcsoftgroup.test.activities.Single_view.class);
A.putExtra("Key", Post_Key);
startActivity(A);}
});
viewHolder.setUsername(model.getUsername());
viewHolder.setProfile(getActivity().getApplicationContext(), model.getProfile());
viewHolder.setDescribe(model.getDescribe());
viewHolder.setWallpaper(getActivity().getApplicationContext(), model.getWallpaper());
viewHolder.setLike(Post_Key);
viewHolder.setLikeNum(Post_Key);
viewHolder.setCommentNum(Post_Key);
viewHolder.mPostTime.setText(model.getTime());
viewHolder.mLike.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mProcessLike = true;
mDatabaseLike.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (mProcessLike) {
if (dataSnapshot.child(Post_Key).hasChild(mCurrentUser.getUid())) {
mDatabaseLike.child(Post_Key).child(mCurrentUser.getUid()).removeValue();
mProcessLike = false;
} else {
mDatabaseLike.child(Post_Key).child(mCurrentUser.getUid()).setValue("LIKED");
mProcessLike = false;
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
});
viewHolder.mShare.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
//sendIntent.putExtra(Intent.EXTRA_TEXT,viewHolder.mComment.getText().toString());
sendIntent.setType("text/plain");
Intent.createChooser(sendIntent, "Share via");
startActivity(sendIntent);
}
});
mRefreshLayout.setRefreshing(false);
mRefreshLayout.setEnabled(true);
}
};
mPostList.setAdapter(firebaseRecyclerAdapter);}
public static class PostViewHolder extends RecyclerView.ViewHolder{
//Main
View mView;
ImageButton mLike;
ImageButton mCommentBtn;
ImageButton mShare;
//Firebase
FirebaseAuth mAuth;
FirebaseUser mCurrentUser;
DatabaseReference mDatabaseLike;
DatabaseReference mDatabaseComment;
public PostViewHolder(View itemView) {
super(itemView);
//Main
mView=itemView;
mLike=(ImageButton) mView.findViewById(R.id.PostLike);
mCommentBtn = (ImageButton) mView.findViewById(R.id.PostCommentBtn);
mShare = (ImageButton) mView.findViewById(R.id.PostShare);
//Firebase
mAuth =FirebaseAuth.getInstance();
mCurrentUser=mAuth.getCurrentUser();
mDatabaseComment = FirebaseDatabase.getInstance().getReference().child("Comments");
mDatabaseLike= FirebaseDatabase.getInstance().getReference().child("Likes");
mDatabaseLike.keepSynced(true);
mDatabaseComment.keepSynced(true);
}
//Like
void setLike(final String Post_Key){
mDatabaseLike.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.child(Post_Key).hasChild(mCurrentUser.getUid())){
mLike.setImageResource(R.drawable.like_icon);
}else {mLike.setImageResource(R.drawable.unlike_icon);}}
#Override
public void onCancelled(DatabaseError databaseError) {}});}
void setLikeNum(final String Post_Key){
mDatabaseLike.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String A = String.valueOf(dataSnapshot.child(Post_Key).getChildrenCount());
TextView PostLikeNum = (TextView) mView.findViewById(R.id.PostLikeNum);
PostLikeNum.setText(A);}
#Override
public void onCancelled(DatabaseError databaseError) {}});}
void setCommentNum(final String Post_Key){
mDatabaseComment.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String C = String.valueOf(dataSnapshot.child(Post_Key).getChildrenCount());
TextView PostCommentNum = (TextView) mView.findViewById(R.id.PostCommentNum);
PostCommentNum.setText(C);}
#Override
public void onCancelled(DatabaseError databaseError) {}});}
//Username
public void setUsername(String Username){
TextView PostUsername = (TextView) mView.findViewById(R.id.PostUsername);
PostUsername.setText(Username);}
//Profile
void setProfile(Context ctx2, String Profile){
ImageView PostProfile = (ImageView) mView.findViewById(R.id.PostUserImage);
if (Profile == null){PostProfile.setVisibility(View.VISIBLE);}
else {PostProfile.setVisibility(View.VISIBLE);
Picasso.with(ctx2).load(Profile).resize(120,120).into(PostProfile);}}
//Describe
void setDescribe(String Describe){
TextView PostDescribe = (TextView) mView.findViewById(R.id.PostDesc);
PostDescribe.setText(Describe);}
//Image Load
void setWallpaper(Context ctx, String Image){
ImageView PostWallpaper = (ImageView) mView.findViewById(R.id.PostWallpaper);
if (Image == null){PostWallpaper.setVisibility(View.VISIBLE);}
else {
PostWallpaper.setVisibility(View.VISIBLE);
Picasso.with(ctx).load(Image).resize(1200,600).into(PostWallpaper);}}
}}
And here's my getter and setter java:
public class Getting_Posts {
private String Username;
private String Profile;
private String Describe;
private String Wallpaper;
public Getting_Posts() {
}
public Getting_Posts(String Username, String Profile, String Describe, String Wallpaper) {
this.Username = Username;
this.Profile = Profile;
this.Describe = Describe;
this.Wallpaper = Wallpaper;
}
public String getDescribe() {
return Describe;
}
public void setDescribe(String describe) {
Describe = describe;
}
public String getWallpaper() {
return Wallpaper;
}
public void setWallpaper(String wallpaper) {
Wallpaper = wallpaper;
}
public String getUsername() {
return Username;
}
public void setUsername(String username) {
Username = username;
}
public String getProfile() {
return Profile;
}
public void setProfile(String profile) {
Profile = profile;
}
}

Using Green DAO with content provider get error

I use GreenDao to generate ContentProvider and when I trying to use it went wrong.it tell me "DaoSession must be set during content provider is active".I dont know where to set the DaoSession.
ContentProvider class as follows
public class ContactContentProvider extends ContentProvider {
public static final String AUTHORITY = "com.junsucc.www.provider";
public static final String BASE_PATH = "contact";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + BASE_PATH);
public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE
+ "/" + BASE_PATH;
public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE
+ "/" + BASE_PATH;
private static final String TABLENAME = ContactDao.TABLENAME;
private static final String PK = ContactDao.Properties.Id
.columnName;
private static final int CONTACT_DIR = 0;
private static final int CONTACT_ID = 1;
private static final UriMatcher sURIMatcher;
static {
sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
sURIMatcher.addURI(AUTHORITY, BASE_PATH, CONTACT_DIR);
sURIMatcher.addURI(AUTHORITY, BASE_PATH + "/#", CONTACT_ID);
}
public DaoSession daoSession=BaseApplication.getDaoSession();
#Override
public boolean onCreate() {
// if(daoSession == null) {
// throw new IllegalStateException("DaoSession must be set before content provider is created");
// }
DaoLog.d("Content Provider started: " + CONTENT_URI);
return true;
}
protected SQLiteDatabase getDatabase() {
if (daoSession == null) {
throw new IllegalStateException("DaoSession must be set during content provider is active");
}
return daoSession.getDatabase();
}
......
the error as follow
java.lang.IllegalStateException: DaoSession must be set during content provider is active
at com.junsucc.www.ContactContentProvider.getDatabase(ContactContentProvider.java:71)
at com.junsucc.www.ContactContentProvider.insert(ContactContentProvider.java:83)
at android.content.ContentProvider$Transport.insert(ContentProvider.java:220)
at android.content.ContentResolver.insert(ContentResolver.java:1190)
at com.junsucc.junsucc.MD5UtilsTest.testProvider(MD5UtilsTest.java:58)
at java.lang.reflect.Method.invokeNative(Native Method)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:554)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1701)
but I had setted th DaoSession inside my Application
public class BaseApplication extends Application {
private static Context mContext;
private static DaoMaster mDaoMaster;
private static DaoSession mDaoSession;
public static DaoMaster getDaoMaster() {
return mDaoMaster;
}
public static Context getContext() {
return mContext;
}
#Override
public void onCreate() {
mContext = getApplicationContext();
DaoMaster.OpenHelper helper = new DaoMaster.DevOpenHelper(mContext, Constants.DB_NAME, null);
mDaoMaster = new DaoMaster(helper.getWritableDatabase());
mDaoSession = mDaoMaster.newSession();
super.onCreate();
}
}
Follow the advice of the framework
/**
* This must be set from outside, it's recommended to do this inside your Application object.
* Subject to change (static isn't nice).
*/
public static DaoSession daoSession;
In your applicaction code
#Override
public void onCreate() {
super.onCreate();
DaoMaster.OpenHelper helper = new DaoMaster.DevOpenHelper(this, Constants.DB_NAME, null);
mDaoMaster = new DaoMaster(helper.getWritableDatabase());
mDaoSession = mDaoMaster.newSession();
/***********************************************/
ContactContentProvider.daoSession = mDaoSession;
/***********************************************/
}
Because ContentProvider is created ahead of Application.
So daoSession will be null when ContentProvider created.

GWT 2.1 Places example without Activities

does anyone have any examples of how to using Places without using activities for history management. I knocked something up quickly and can see the url changing with browser-back and browser-forward clicks but the display doesn't go anywhere.
I'm using a DecoratedTabPanel and have a SelectionHandler that fires off getPlaceController().goTo(place).
Any ideas would be useful.
Here is a simple piece of code that I've made to demonstrate what you expected. It's based on the GWT and MVP Development document (GWT and MVP)
In this example you navigate between two tabs. On selection, a new history item is created (without any activity). As long as you use browser buttons to go back/forward the page will be updated correctly.
I have defined one place, one activity and its view. I've adjusted AppActivityMapper, AppActivityManager and ClientFactory to my needs. The code is lightweight and doesn't need comments to be understood. I've only put some explanations when it was needed, but if it's not clear do not hesitate to ask.
ExampleView.java
public interface ExampleView extends IsWidget {
void selectTab(int index);
}
ExampleViewImpl.java
public class ExampleViewImpl extends Composite implements ExampleView, SelectionHandler<Integer> {
private DecoratedTabPanel panel;
public ExampleViewImpl() {
panel = new DecoratedTabPanel();
initComposite();
initWidget(panel);
}
private void initComposite() {
panel.add(new HTML("Content 1"), "Tab 1");
panel.add(new HTML("Content 2"), "Tab 2");
panel.selectTab(0);
panel.addSelectionHandler(this);
}
#Override
public void selectTab(int index) {
if (index >=0 && index < panel.getWidgetCount()) {
if (index != panel.getTabBar().getSelectedTab()) {
panel.selectTab(index);
}
}
}
#Override
public void onSelection(SelectionEvent<Integer> event) {
// Fire an history event corresponding to the tab selected
switch (event.getSelectedItem()) {
case 0:
History.newItem("thetabplace:1");
break;
case 1:
History.newItem("thetabplace:2");
break;
}
}
}
ClientFactory.java
public class ClientFactory {
private final EventBus eventBus = new SimpleEventBus();
private final PlaceController placeController = new PlaceController(eventBus);
private final ExampleViewImpl example = new ExampleViewImpl();
public EventBus getEventBus() {
return this.eventBus;
}
public PlaceController getPlaceController() {
return this.placeController;
}
public ExampleViewImpl getExampleView() {
return example;
}
}
ExampleActivity.java
public class ExampleActivity extends AbstractActivity {
private ExampleView view;
private ClientFactory factory;
public ExampleActivity(ExamplePlace place, ClientFactory factory) {
// Get the factory reference
this.factory = factory;
// Get the reference to the view
view = this.factory.getExampleView();
// Select the tab corresponding to the token value
if (place.getToken() != null) {
// By default the first tab is selected
if (place.getToken().equals("") || place.getToken().equals("1")) {
view.selectTab(0);
} else if (place.getToken().equals("2")) {
view.selectTab(1);
}
}
}
#Override
public void start(AcceptsOneWidget panel, EventBus eventBus) {
// Attach this view to the application container
panel.setWidget(view);
}
}
ExamplePlace.java
/**
* Just an very basic place
*/
public class ExamplePlace extends Place {
// The token corresponding to an action
private String token;
// This place should use a token to identify a view behavior
public ExamplePlace(String token) {
this.token = token;
}
// Return the current token
public String getToken() {
return token;
}
// Custom prefix to break the default name : ExamplePlace
// So that the history token will be thetabplace:token
// and not any more : ExamplePlace:token
#Prefix(value="thetabplace")
public static class Tokenizer implements PlaceTokenizer<ExamplePlace> {
#Override
public String getToken(ExamplePlace place) {
return place.getToken();
}
#Override
public ExamplePlace getPlace(String token) {
return new ExamplePlace(token);
}
}
}
AppActivityMapper.java
public class AppActivityMapper implements ActivityMapper {
private ClientFactory clientFactory;
public AppActivityMapper(ClientFactory clientFactory) {
super();
this.clientFactory = clientFactory;
}
#Override
public Activity getActivity(Place place) {
if (place instanceof ExamplePlace) {
return new ExampleActivity((ExamplePlace) place, clientFactory);
}
return null;
}
}
AppPlaceHistoryMapper.java
#WithTokenizers({ExamplePlace.Tokenizer.class})
public interface AppPlaceHistoryMapper extends PlaceHistoryMapper
{
}
All together
private Place defaultPlace = new ExamplePlace("1");
private SimplePanel appWidget = new SimplePanel();
public void onModuleLoad() {
ClientFactory clientFactory = new ClientFactory();
EventBus eventBus = clientFactory.getEventBus();
PlaceController placeController = clientFactory.getPlaceController();
// Start ActivityManager for the main widget with our ActivityMapper
ActivityMapper activityMapper = new AppActivityMapper(clientFactory);
ActivityManager activityManager = new ActivityManager(activityMapper, eventBus);
activityManager.setDisplay(appWidget);
// Start PlaceHistoryHandler with our PlaceHistoryMapper
AppPlaceHistoryMapper historyMapper= GWT.create(AppPlaceHistoryMapper.class);
PlaceHistoryHandler historyHandler = new PlaceHistoryHandler(historyMapper);
historyHandler.register(placeController, eventBus, defaultPlace);
RootPanel.get().add(appWidget);
// Goes to the place represented on URL else default place
historyHandler.handleCurrentHistory();
}