Android getDeclaredFields value

3

I am doing an android studies, I do not handle much of the subject since I am starting now, I would like to create a simple mvc of CRUD, where I want to call model.save() ;

Then I created the following structure:

MainActivity.java

Produto produto1 = new Produto(this);
produto1.setId(1);
produto1.setNome("CELULAR");
produto1.setPreco(5.5);
produto1.Save();

Product.java

@DatabaseTable (tableName = "produtos") 
public class Produto extends BaseModel{

     @DatabaseField(columnName="id",    columnType="INTEGER", primaryKey=true)
     private int id;

     @DatabaseField(columnName="nome", columnType="VARCHAR")
     private String nome;

     @DatabaseField(columnName="preco", columnType="DOUBLE", columnSize="10,9")
     private Double preco;

     @DatabaseField(columnName="endereco", columnType="TEXT", columnSize="50", canBeNull=true, defaultValue="NULL", unique=true)
     private Double endereco;

     public int getId() {return id;}
     public void setId(int id) {this.id = id;}
     public String getNome() {return nome;}
     public void setNome(String nome) {this.nome = nome;}
     public Double getPreco() {return preco;}
     public void setPreco(Double preco) {this.preco = preco;}

     public Produto(Context context) {
         super(context);
     }  
}

DatabaseTable.java

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE) //can use in method only.
public @interface DatabaseTable {
    String tableName();  
}

DatabaseField.java

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD) //can use in method only.
public @interface DatabaseField {
     String columnName() default "";  
     String columnType(); 
     String defaultValue() default "";
     String columnSize() default "";
     boolean canBeNull() default true; 
     boolean unique() default false; 
     boolean primaryKey() default false; 
     boolean autoIncrement() default false; 
}

BaseModel.java

public class BaseModel extends DBFactory<BaseModel> {
 public BaseModel(Context context) {
      super(context);
 }
}

DBFactory.java

public class DBFactory<T> extends SQLiteOpenHelper {
    private static final String DB_NAME = "VendasDB";
    private static final int DATABASE_VERSION  = 1;
    private final Context myContext;
    private static DBFactory mInstance = null;
    private static SQLiteDatabase myWritableDb;

    private Class t;
    public void set(Class t) { this.t = t; }
    public Class get() { return t; }

    public DBFactory(Context pContext){         
        super(pContext, DB_NAME, null, DATABASE_VERSION);
        this.myContext = pContext;
        this.set((Class) this.getClass());    
        Log.v("CreateTableOnModel",CreateTableOnModel());
    }

    public String Save()
    {
        Log.v("DBFactory", "SAVE()");
        Class clazz = get();

        DatabaseTable annot = (DatabaseTable) clazz.getAnnotation(DatabaseTable.class);
        StringBuilder sb = new StringBuilder();

        if(!annot.tableName().equals(""))
        {
            Field[] fields = clazz.getDeclaredFields();
            Field idField = null;

            try {
               idField = clazz.getDeclaredField("id");      
               idField.setAccessible(true);
               Object b = idField.get(get().newInstance());
               Log.v("idField:", b.toString());
            } catch (Exception nsfe) {
               System.out.println(nsfe.toString());
            }


        }
    }
}

Error:

03-31 16:26:23.780: I/System.out(32048): java.lang.InstantiationException: can't instantiate class br.com.rlsystem.vendas.model.Produto; no empty constructor
    
asked by anonymous 31.03.2014 / 21:34

1 answer

1

The error occurs because you are trying to create an instance without passing arguments in the constructor of a class ( Produto ) that has parameters:

public Produto(Context context) {
    super(context);
}  

There are two outputs to solve the problem:

  • Remove the constructor with arguments and set the dependency on a setter .

  • Retrieve a reference to the builder and use newInstance fault of the constructor" passing the necessary arguments.

  • Update

    The get() method of the Field class needs the instance of an object to retrieve the value of the attribute.

    The problem in this case is that you are creating another empty object.

    As Produto extends DBFactory indirectly, you need to reference the object itself, in case:

    Object b = idField.get(this);
    
        
    31.03.2014 / 22:14