Save List of PropertyBusinessObjects to the Storage - codenameone

I need to save a dinamic List of PropertyBusinessObjects to the Storage, but I didn't find how to do that. I should be able to add and remove items from the list.
The following test code throws java.io.IOException: Object type not supported: CollectiveDAO. I use registerExternalizable().
public class TestSaveListDAOs {
private Form current;
private Resources theme;
public static List<CollectiveDAO> collectivesDB = new ArrayList<>();
public void init(Object context) {
[...]
}
public void start() {
if(current != null){
current.show();
return;
}
Form hi = new Form("Hi World", BoxLayout.y());
hi.add(new Label("Hi World"));
hi.show();
restoreDB();
collectivesDB.add(new CollectiveDAO());
collectivesDB.add(new CollectiveDAO());
saveDB();
restoreDB();
}
public void stop() {
[...]
}
public void destroy() {
}
public static void saveDB() {
for (CollectiveDAO collectiveDAO : collectivesDB) {
collectiveDAO.getPropertyIndex().registerExternalizable();
}
Storage.getInstance().writeObject("CollectivesDB", collectivesDB);
}
private static void restoreDB() {
Object restoredCollectivesDB = Storage.getInstance().readObject("CollectivesDB");
if (restoredCollectivesDB != null) {
collectivesDB = ((List) restoredCollectivesDB);
}
}
}
public class CollectiveDAO implements PropertyBusinessObject {
public final Property<String, CollectiveDAO> collectiveID = new Property<>("collectiveID");
private final PropertyIndex idx = new PropertyIndex(this, "CollectiveDAO",
collectiveID);
#Override
public PropertyIndex getPropertyIndex() {
return idx;
}
}

I'd use JSON rather than Externalizable such as:
public static void saveDB() {
PropertyIndex.storeJSONList("CollectivesDB", collectivesDB);
}
private static void restoreDB() {
collectivesDB = new CollectiveDAO().getPropertyIndex().loadJSONList("CollectivesDB");
}
It's shorter with nicer output. However, if you want to use Externalizable your usage is incorrect. You should remove the for call and instead do:
public void init(Object context) {
new CollectiveDAO().getPropertyIndex().registerExternalizable();
[...]
}
This is needed only once for reading and writing (it was missing for reading). As it registers the new object type (CollectiveDAO).

Related

Data not inserting into the Database room Android

I'm new to android and this is the first time I'm using room in my application. Either insert operation is not performed or the database is not created or any other error.
I don't know what I'm doing wrong so I need your help.
This program is running but No result is displayed. Nothing is showing on the screen.
Here is my code-
please let me know what is wrong in this code and what I should do to correct it.
Car_details.java
#PrimaryKey
#NonNull
#SerializedName("id")
#Expose
private String id;
#SerializedName("name")
#Expose
private String name;
#SerializedName("desc")
#Expose
private String desc;
#SerializedName("image")
#Expose
private String image;
CarDao.java-
#Insert(onConflict = OnConflictStrategy.REPLACE)
void insert(Car_Details car_details);
#Query("Select * from car_table")
LiveData<List<Car_Details>> selectAll();
CarListDatabase.java
private static CarListDatabase instance;
public abstract CarDao carDao();
public static synchronized CarListDatabase getInstance(Context context){
if(instance==null)
{
instance= Room.databaseBuilder(context.getApplicationContext(),
CarListDatabase.class,"Car_database").fallbackToDestructiveMigration()
.build();
}
return instance;
}
CarRepository.java
public void getCarList(){
CarlistInterface carlistInterface= retrofit.create(CarlistInterface.class);
Call<List<Car_Details>> carList= carlistInterface.carList();
carList.enqueue(new Callback<List<Car_Details>>() {
#Override
public void onResponse(Call<List<Car_Details>> call, final Response<List<Car_Details>> response) {
if(response.body() != null){
List<Car_Details> car_details = response.body();
for (int i = 0; i < car_details.size(); i++) {
String id=car_details.get(i).getId();
String names = car_details.get(i).getName();
String desc=car_details.get(i).getDesc();
String image= car_details.get(i).getImage();
Car_Details car = new Car_Details();
car .setId(id);
car .setName(names);
car .setDesc(desc);
car .setImage(image);
new InsertNoteAsyncTask(carDao).execute(car);
}
}
}
});
}
public LiveData<List<Car_Details>> getCarLists(){
return allCarList;
}
private static class InsertNoteAsyncTask extends AsyncTask<Car_Details,Void,Void> {
private CarDao carDao;
private InsertNoteAsyncTask(CarDao carDao){
this.carDao= carDao;
}
#Override
protected Void doInBackground(Car_Details... car_details) {
carDao.insert(car_details[0]);
return null;
}
CarViewModel.java
public CarViewModel(#NonNull Application application) {
super(application);
repository= new CarRepository(application);
carList= repository.getCarLists();
}
public LiveData<List<Car_Details>> getListLiveData() {
return carList;
MainActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
repository = new CarRepository(this);
carViewModel = ViewModelProviders.of(this).get(CarViewModel.class);
recyclerView= findViewById(R.id.cars_recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
List = new ArrayList<>();
recyclerAdapter = new RecyclerAdapter(List);
recyclerView.setAdapter(recyclerAdapter);
recyclerAdapter = new RecyclerAdapter(List);
recyclerView.setAdapter(recyclerAdapter);
carViewModel.getListLiveData().observe(this, new
Observer<java.util.List<Car_Details>>() {
#Override
public void onChanged(java.util.List<Car_Details> car_details) {
recyclerAdapter.setUserList(List);
}
});
repository.getCarList();
}
RecyclerAdapter.java
public class RecyclerAdapter extends RecyclerView.Adapter {
List<Car_Details> carList= new ArrayList<>();
public RecyclerAdapter(List<Car_Details> carList) {
this.carList = carList;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater= LayoutInflater.from(parent.getContext());
View view= layoutInflater.inflate(R.layout.row_item,parent,false);
return new RecyclerAdapter.ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.car_name.setText(carList.get(position).getName());
holder.car_desc.setText(carList.get(position).getDesc());
}
public void setUserList(List<Car_Details> userList) {
this.carList = userList;
notifyDataSetChanged();
}
#Override
public int getItemCount() {
return carList.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
private TextView car_name,car_desc;
public ViewHolder(#NonNull View itemView) {
super(itemView);
car_name= itemView.findViewById(R.id.car_name);
car_desc= itemView.findViewById(R.id.car_desc);
}
}
}
#Override
public int getItemCount() {
return carList.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
private TextView car_name,car_desc;
public ViewHolder(#NonNull View itemView) {
super(itemView);
car_name= itemView.findViewById(R.id.car_name);
car_desc= itemView.findViewById(R.id.car_desc);
}
}
}
There is nothing wrong with your insert operation with room.
The way you have used live date in your application seems wrong that's why your program is running but no result is coming.
You have to check the part where you are using live data.
Hope this help you out.

How to display data in firestore with recyclerview in frgaments?

I'm new to android programming and I have a problem in displaying data from firestore. I want to display the data in fragments in the navigation drawer. I found tutorials that display it on activities but nothing in fragments. Please help me with this.
public class MainActivity extends AppCompatActivity {
Toolbar toolbar;
DrawerLayout drawerLayout;
ActionBarDrawerToggle actionBarDrawerToggle;
NavigationView navigationView;
FragmentTransaction fragmentTransaction;
private boolean shouldLoadProductFragOnBackPress = false;
public static int navItemIndex = 0;
public FirebaseAuth mAuth;
FirebaseFirestore db = FirebaseFirestore.getInstance();
private void Load_Product_fragment() {
navItemIndex = 0;
fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.maincontainer,new ProductFragment());
fragmentTransaction.commit();
getSupportActionBar().setTitle(R.string.Productfragment_Title);
drawerLayout.closeDrawers();
}
private void Load_Service_fragment(){
navItemIndex = 1;
fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.maincontainer,new ServiceFragment());
fragmentTransaction.commit();
getSupportActionBar().setTitle(R.string.Servicefragmnet_Title);
drawerLayout.closeDrawers();
shouldLoadProductFragOnBackPress = true;
}
private void Load_Account_fragment(){
navItemIndex = 2;
fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.maincontainer,new AccountFragment());
fragmentTransaction.commit();
getSupportActionBar().setTitle(R.string.Accountfragment_Title);
drawerLayout.closeDrawers();
shouldLoadProductFragOnBackPress = true;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar=(Toolbar)findViewById(R.id.Toolbar_Layout);
setSupportActionBar(toolbar);
drawerLayout=(DrawerLayout) findViewById(R.id.Drawer_Layout);
actionBarDrawerToggle = new ActionBarDrawerToggle(this,drawerLayout,toolbar,R.string.drawer_open,R.string.drawer_close);
drawerLayout.addDrawerListener(actionBarDrawerToggle);
drawerLayout.openDrawer(Gravity.LEFT);
Load_Product_fragment();
navigationView= findViewById(R.id.Navigation_View);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId())
{
case R.id.Productsfragment_ND:
Load_Product_fragment();
item.setChecked(true);
break;
case R.id.Servicefragment_ND:
Load_Service_fragment();
item.setChecked(true);
break;
case R.id.Accountfragemnt_ND:
Load_Account_fragment();
item.setChecked(true);
break;
}
return false;
}
});
}
#Override
public void onBackPressed() {
if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
drawerLayout.closeDrawers();
return;
}
// This code loads home fragment when back key is pressed
// when user is in other fragment than home
if (shouldLoadProductFragOnBackPress) {
// checking if user is on other navigation menu
// rather than home
if (navItemIndex !=0) {
navItemIndex = 0;
shouldLoadProductFragOnBackPress = false;
Load_Product_fragment();
return;
}
}
super.onBackPressed();
}
#Override
protected void onPostCreate(#Nullable Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
actionBarDrawerToggle.syncState();
}
public void del(View view) {db.collection("products").document("test")
.delete()
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
}
});
}
}
This is my main-activity.It contains the requirements for a navigation drawer for 3 fragments.I have a Firestore database linked to the app. I need to display the contents of the database in these fragments.
Next i will show one fragment and the recyclerview adapter and view holder i have tried using.
I am not sure if it is the correct way to do it.Please help me with this
public class ProductFragment extends Fragment {
private static final String TAG = ProductFragment.class.getSimpleName();
private RecyclerView recipeRecyclerview;
private LinearLayoutManager linearLayoutManager;
private Product_adapter mAdapter;
private DatabaseReference mDatabaseRef;
private DatabaseReference childRef;
public ProductFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate (R.layout.fragment_product, container, false);
getActivity().setTitle(getString(R.string.Productfrag_title));
linearLayoutManager = new LinearLayoutManager(getActivity());
recipeRecyclerview = view.findViewById(R.id.List_recycleview);
recipeRecyclerview.setHasFixedSize(true);
mDatabaseRef = FirebaseDatabase.getInstance().getReference();
childRef = mDatabaseRef.child("recipes");
mAdapter = new Product_adapter(Product_response.class, R.layout.list_layout, View_holder.class, childRef, getContext());
recipeRecyclerview.setLayoutManager(linearLayoutManager);
recipeRecyclerview.setAdapter(mAdapter);
return view;
}
}
This is my products-fragment. I have tried to add the recycler view.
Adapter
public class Product_adapter extends RecyclerView.Adapter {
FirebaseFirestore db = FirebaseFirestore.getInstance();
private Context context;
Query query = db.collection("products");
FirestoreRecyclerOptions<Product_response> response = new FirestoreRecyclerOptions.Builder<Product_response>()
.setQuery(query, Product_response.class)
.build();
FirestoreRecyclerAdapter adapter = new FirestoreRecyclerAdapter<Product_response, View_holder>(response) {
#Override
protected void onBindViewHolder(View_holder holder, int position, Product_response model) {
}
#Override
public View_holder onCreateViewHolder(ViewGroup group, int i) {
// Create a new instance of the ViewHolder, in this case we are using a custom
// layout called R.layout.message for each item
View view = LayoutInflater.from(group.getContext())
.inflate(R.layout.list_layout, group, false);
return new View_holder(view);
}
};
public Product_adapter(Class<Product_response> product_responseClass, int list_layout, Class<View_holder> view_holderClass, DatabaseReference childRef, Context context) {
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return null;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
}
#Override
public int getItemCount() {
return 0;
}
}
View holder
public class View_holder extends RecyclerView.ViewHolder{
private static final String TAG = View_holder.class.getSimpleName();
public TextView main_text, subtext ;
public ImageView image;
public View_holder(View itemView) {
super(itemView);
main_text = (TextView)itemView.findViewById(R.id.List_maintext);
subtext = (TextView)itemView.findViewById(R.id.List_subtext);
image = (ImageView)itemView.findViewById(R.id.List_imageview);
}
}
Next i will show the response page where i used the getter and setter for the firebase
import com.google.firebase.firestore.IgnoreExtraProperties;
#IgnoreExtraProperties
public class Product_response {
private String Product;
private String Cost;
public Product_response() {
}
public Product_response(String Product, String Cost){
this.Product= Product;
this.Cost= Cost;
}
public String getProduct() {
return Product;
}
public void setProduct(String Product) {
this.Product = Product;
}
public String getCost(){
return Cost;
}
public void setCost(String Cost)
{
this.Cost = Cost;
}
}
This is how my database looks like. I need to display this products in my fragment
This is the github link of the app. Please help me complete this

Accessing XML Image Array within an ImageAdapter

My question is very similar to this thread, however it was never properly answered.
I have an ImageAdapter setup as so;
public class ImageAdapter extends BaseAdapter {
private Context mContext;
int[] mImages;
public ImageAdapter(Context c, int[] images) {
mContext = c;
mImages = images;
}
#Override
public int getCount() {
return 0;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
// if it's not recycled, initialize some attributes
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(200, 200));
} else {
imageView = (ImageView) convertView;
}
imageView.setImageResource(mImages[position]);
return imageView;
}
}
And I want the images to be from an XML;
<integer-array name="images">
<item>#drawable/image1</item>
<item>#drawable/image2</item>
<item>#drawable/image3</item>
</integer-array>
In my MainActivity class I have tried to get the image array and pass it into the ImageAdapter but I can't;
public class MainActivity extends AppCompatActivity {
private int images[] = getResources().getIntArray(R.array.images);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GridView gridview = (GridView) findViewById(R.id.gridView);
gridview.setAdapter(new ImageAdapter(MainActivity.this, images));
}
}
I am currently getting an error message:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
with my app crashing on load up. I want to make my ImageAdapter display images from an XML in my GridView.
try to use
private int images[] = {R.drawable.image1, R.drawable.image3, R.drawable.image3};
instead of
private int images[] = getResources().getIntArray(R.array.images);

synchronizing only the assigning of a static variable

I have a static variable which will be fetched a lot. I want to synchronize the initialization, but want it to be lazy loaded. So not making it final.
Is this a correct/acceptable approach ?
Here is the code.
public class Test {
private static Object staticObj;
public static Object getStaticObj() throws Exception{
if(staticObj == null){
assignNewStaticObj();
}
return staticObj;
}
private static void assignNewStaticObj(){
synchronized(staticObj){
if (staticObj == null) {
staticObj = new Object();
}
}
}
}
You can synchronize on something else that is static, cheap and not lazy:
public class Test {
...
private static Object staticObjSync = new Object();
...
private static void assignNewStaticObj() {
synchronized(staticObjSync) {
...

My application usage memory remained high even after clear all my objects list

So i have this Base Class:
public abstract class WiresharkFile : IDisposable
{
private string _fileName;
private int _packets;
private int _packetsSent;
private string _duration;
private double _speed;
private int _progress;
protected abstract WiresharkFilePacket ReadPacket();
public abstract IEnumerator<WiresharkFilePacket> GetEnumerator();
public abstract void Rewind();
public string FileName
{
get { return _fileName; }
set { _fileName = value; }
}
public int Packets
{
get { return _packets; }
set { _packets = value; }
}
public void Dispose()
{
// implemented inside sub class.
}
}
And specific Wireshark format (libpcap):
public class Libpcap : WiresharkFile, IDisposable, IEnumerable<WiresharkFilePacket>
{
private BinaryReader binaryReader;
private Version version;
private uint snaplen;
private int thiszone;
private uint sigfigs;
private LibpcapLinkType linktype;
private long basePos;
private bool byteSwap;
private static uint MAGIC = 0xa1b2c3d4;
private static uint MAGIC_ENDIAN = 0xd4c3b2a1;
public Libpcap(string path)
: this(new FileStream(path, FileMode.Open, FileAccess.Read))
{
FileName = path;
}
private Libpcap(Stream fileStream)
{
...
}
public override void Rewind()
{
binaryReader = new BinaryReader(new FileStream(FileName, FileMode.Open, FileAccess.Read));
binaryReader.BaseStream.Position = basePos;
}
public void Dispose()
{
if (binaryReader != null)
binaryReader.Close();
}
I removed almost all parts of how i am read this file
Add files in to my application
I have this objects list:
public ObservableCollection<WiresharkFile> wiresharkFiles { get; set; }
This list is binding into my ListView.
When the user choose files to add into my application:
string[] files = openFileDialog.FileNames;
I am check this files via another class:
public class FileValidation
{
public static void DoWork(IEnumerable<string> files)
{
CancellationTokenSource tokenSource = new CancellationTokenSource();
CancellationToken token = tokenSource.Token;
Task task = Task.Factory.StartNew(() =>
{
try
{
Parallel.ForEach(files,
new ParallelOptions
{
MaxDegreeOfParallelism = 3
},
file =>
{
ProcessFile(file);
});
}
catch (Exception)
{ }
}, tokenSource.Token,
TaskCreationOptions.None,
TaskScheduler.Default).ContinueWith
(t =>
{
if (FinishValidationEventHandler != null)
FinishValidationEventHandler();
}
, TaskScheduler.FromCurrentSynchronizationContext()
);
}
private static void ProcessFile(string file)
{
ReadWiresharkFormat(file);
using (WiresharkFile wiresharkFile = new Libpcap(file))
{
WiresharkFileInfo.ReadInfo(wiresharkFile);
// Add file into my list.
}
}
private static WiresharkFileFormat ReadWiresharkFormat(string file)
{
using (BinaryReader binaryReader = new BinaryReader(File.Open(file, FileMode.Open, FileAccess.Read)))
{
// Open file and read first 4 bytes in order to verify file type.
}
}
private static void ReadInfo(WiresharkFile wiresharkFile)
{
foreach (WiresharkFilePacket packet in wiresharkFile)
{
// Collect file information (number of packets...)
}
}
}
OK so until here all good.
Now when add many files, lets say (1000+-) i can see that my memory usage is growing in 200MB but after clear this list the memory usage not changed.
Any idea what could cause this ?

Resources