Henrique Becker Henrique Becker - 27 days ago 15
Android Question

RealmRecyclerViewAdapter does not work

I am developing a Android App and will use Realm (this is my first App with Realm). But I have problems with my recyclerviewadapter.

I am getting an FATAL EXCEPTION

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.udacity.stockhawk, PID: 9880
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.udacity.stockhawk/com.udacity.stockhawk.ui.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'io.realm.RealmList com.udacity.stockhawk.data.Parent.getStockList()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2521)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2595)
at android.app.ActivityThread.access$800(ActivityThread.java:178)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1470)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5631)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:959)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:754)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'io.realm.RealmList com.udacity.stockhawk.data.Parent.getStockList()' on a null object reference
at com.udacity.stockhawk.ui.MainActivity.onCreate(MainActivity.java:66)
at android.app.Activity.performCreate(Activity.java:6092)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1112)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2468)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2595) 
at android.app.ActivityThread.access$800(ActivityThread.java:178) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1470) 
at android.os.Handler.dispatchMessage(Handler.java:111) 
at android.os.Looper.loop(Looper.java:194) 
at android.app.ActivityThread.main(ActivityThread.java:5631) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:959) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:754) 


My adapter is this:

class StockAdapter extends RealmRecyclerViewAdapter<Stock, StockAdapter.StockViewHolder> {
private final Context context;
private final DecimalFormat dollarFormatWithPlus;
private final DecimalFormat dollarFormat;
private final DecimalFormat percentageFormat;
private final StockAdapterOnClickHandler clickHandler;

StockAdapter(Context context, StockAdapterOnClickHandler clickHandler,
OrderedRealmCollection<Stock> data) {
super(context, data, true);
this.context = context;
this.clickHandler = clickHandler;

dollarFormat = (DecimalFormat) NumberFormat.getCurrencyInstance(Locale.US);
dollarFormatWithPlus = (DecimalFormat) NumberFormat.getCurrencyInstance(Locale.US);
dollarFormatWithPlus.setPositivePrefix("+$");
percentageFormat = (DecimalFormat) NumberFormat.getPercentInstance(Locale.getDefault());
percentageFormat.setMaximumFractionDigits(2);
percentageFormat.setMinimumFractionDigits(2);
percentageFormat.setPositivePrefix("+");
}

@Override
public StockViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

View item = LayoutInflater.from(context).inflate(R.layout.list_item_quote, parent, false);

return new StockViewHolder(item);
}

@Override
public void onBindViewHolder(StockViewHolder holder, int position) {
final Stock stock = getItem(position);

holder.symbol.setText(stock.getDataset_code());
double currentPrice = stock.getQuoteHistory().first().getValue();
double oldPrice = stock.getQuoteHistory().get(1).getValue();
holder.price.setText(dollarFormat.format(currentPrice));
double rawAbsoluteChange = currentPrice - oldPrice;
double percentageChange = (rawAbsoluteChange/oldPrice) * 100.0;

if (rawAbsoluteChange > 0) {
holder.change.setBackgroundResource(R.drawable.percent_change_pill_green);
} else {
holder.change.setBackgroundResource(R.drawable.percent_change_pill_red);
}

String change = dollarFormatWithPlus.format(rawAbsoluteChange);
String percentage = percentageFormat.format(percentageChange / 100);

if (Utils.getDisplayMode(context)
.equals(context.getString(R.string.pref_display_mode_absolute_key))) {
holder.change.setText(change);
} else {
holder.change.setText(percentage);
}


}

interface StockAdapterOnClickHandler {
void onClick(String symbol);
}

class StockViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

@BindView(R.id.symbol)
TextView symbol;

@BindView(R.id.price)
TextView price;

@BindView(R.id.change)
TextView change;

StockViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
itemView.setOnClickListener(this);
}

@Override
public void onClick(View v) {
int adapterPosition = getAdapterPosition();
clickHandler.onClick(getItem(adapterPosition).getDataset_code());
}
}
}


And my activity onCreate code is:

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);
ButterKnife.bind(this);
realm = Realm.getDefaultInstance();
adapter = new StockAdapter(this, this, realm.where(Parent.class).findFirst().getStockList());
stockRecyclerView.setAdapter(adapter);
stockRecyclerView.setLayoutManager(new LinearLayoutManager(this));

swipeRefreshLayout.setOnRefreshListener(this);
swipeRefreshLayout.setRefreshing(true);
onRefresh();

QuoteSyncJob.initialize(this);

new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) {
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}

@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
String symbol = adapter.getItem(viewHolder.getAdapterPosition()).getDataset_code();
Utils.removeStock(realm, symbol);
}

}).attachToRecyclerView(stockRecyclerView);
}


What need I do to resolve this?
The other classes in the project are working.
I used this https://github.com/realm/realm-android-adapters as example

P.S.: This is for my Project 3 on Udacity Nanodegree.

Answer Source

Did you make any changes to your Realm Objects? If you have added, deleted or chenged anything (e.g. filed type or name) you have to clear your whole database and create all objects again.

You can do this using:

Realm.deleteAll()