Android: ArrayList getting nullpointer on second call - java

So I'm working on an android app and currently having an issue with some code. It's quite simple actually... I fill an arraylist, also check if it gets filled (it does) and then request that arraylist later on. But somehow when I request the arraylist later on it's empty and I'm not making a new instance or anything... Or I'm just plain missing it.
So here's the code where it's going wrong...
package net.serellyn.c2m.cal2movement;
import android.app.Activity;
import android.content.SharedPreferences;
import android.graphics.Typeface;
import android.os.Bundle;
import android.util.Log;
import android.widget.AutoCompleteTextView;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import java.util.ArrayList;
public class MainActivity extends Activity implements TaskListener{
private SharedPreferences sharedPreferences;
private SharedPreferences.Editor editor;
private TaskListener listener;
private Exercises exercises;
//...
private ArrayList<String> exerciseArrayList;
//...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setLayout();
sharedPreferences = getSharedPreferences("PreferenceValues", MODE_PRIVATE);
editor = sharedPreferences.edit();
listener = this;
exercises = new Exercises();
new sc_getExercises(listener).execute("http://www.serellyn.net/c2e/app_backend/exercises.php");
}
#Override
public void taskComplete(ArrayList e) {
exercises.setExercises(e);
for(Exercise a : exercises.getExercises()) {
Log.i("DebugInfo", a.getExercise());
}
setLayout();
}
private void setLayout() {
Typeface tf_dinBlack = Typeface.createFromAsset(getAssets(), "DIN_Black.ttf");
Typeface tf_dinMedium = Typeface.createFromAsset(getAssets(), "DIN_Medium.ttf");
Typeface tf_dinLight = Typeface.createFromAsset(getAssets(), "DIN_Light.ttf");
tv_appName = (TextView)findViewById(R.id.tv_appName);
tv_appTagline = (TextView)findViewById(R.id.tv_appTagline);
tv_hourNumber = (TextView)findViewById(R.id.tv_hoursNumber);
tv_hourText = (TextView)findViewById(R.id.tv_hoursText);
tv_minutesNumber = (TextView)findViewById(R.id.tv_minutesNumber);
tv_minutesText = (TextView)findViewById(R.id.tv_minutesText);
tv_yourActivity = (TextView)findViewById(R.id.tv_yourActivity);
s_activities = (Spinner)findViewById(R.id.s_activities);
tv_appName.setTypeface(tf_dinBlack);
tv_appTagline.setTypeface(tf_dinMedium);
tv_hourNumber.setTypeface(tf_dinLight);
tv_hourText.setTypeface(tf_dinLight);
tv_minutesNumber.setTypeface(tf_dinLight);
tv_minutesText.setTypeface(tf_dinLight);
tv_yourActivity.setTypeface(tf_dinLight);
setActivityValues();
}
private void setActivityValues() {
for(Exercise a : exercises.getExercises()) {
Log.i("DebugInfo", a.getExercise());
}
}
}
sc_getExercises is an AsyncTask which works as expected, and fills the 'exercises' array in 'TaskComplete' function. I loop the 'exercises'array to see if it's filled, and it is filled as it should be.
However, when I do the same in the 'setActivityValues' later on, I get a nullpointerexception.
So that's kinda... weird in my eyes. What am I doing wrong?
Here's the exercises class.
package net.serellyn.c2m.cal2movement;
import java.util.ArrayList;
public class Exercises {
private ArrayList<Exercise> exercises;
public Exercises(){
exercises = new ArrayList<Exercise>();
}
public ArrayList<Exercise> getExercises() {
return exercises;
}
public void setExercises(ArrayList<Exercise> exercises) {
this.exercises = exercises;
}
}
I hope someone can spot the problem. Thanks in advance.

This is your method:
private void setActivityValues() {
for(Exercise a : exercises.getExercises()) {
Log.i("DebugInfo", a.getExercise());
}
}
Either exercises is null (it is initialized in onCreate), or exercises in your Exercises class instance is null (gets a value at taskComplete, which invokes setExercises), or one of the exercises in the loop is null, or the getExercise has a NullPointerException bug.

It says nullPointerException, check your json parser it fufills your list properly or not.

Related

How do I pass arrays from a java android activity class to a normal java class?

I'm new to java and am having issues with passing an array between classes. I want to pass data collected from the main activity for another class that is doing calculations. When I try to print the array values to the debug log in my calculations class I get an error "java.lang.NullPointerException: Attempt to read from null array"
Here is my calculations class:
package com.example.pokerholdemcalculator;
import android.util.Log;
public class CardHandling {
private int[] usedCards;
private MainActivity ma;
CardHandling() {
usedCards = new int[13];
ma = new MainActivity();
usedCards = ma.getPlayerCardContents();
}
public void printC () {
for (int i = 0; i < 13; i++) {
String card = Integer.toString(usedCards[i]);
Log.d("CARDS", card);
}
}
}
And my MainActivity class:
package com.example.pokerholdemcalculator;
import android.graphics.PorterDuff;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ViewFlipper;
public class MainActivity extends AppCompatActivity {
private ViewFlipper viewFlipper;
private boolean[] playerCardFlag;
private ImageButton[] playerCard;
private int[] playerCardContents;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
playerCard = new ImageButton[13];
playerCardFlag = new boolean[13];
playerCardContents = new int[13];
}
public void testing (View v) {
printArr();
}
public void printArr() {
CardHandling ch = new CardHandling();
ch.printC();
}
public int[] getPlayerCardContents() {
return playerCardContents;
}
This is the error message from the console:
Caused by: java.lang.NullPointerException: Attempt to read from null array
at com.example.pokerholdemcalculator.MainActivity.getPlayerCardContents(MainActivity.java:70)
at com.example.pokerholdemcalculator.CardHandling.<init>(CardHandling.java:12)
at com.example.pokerholdemcalculator.MainActivity.printArr(MainActivity.java:64)
at com.example.pokerholdemcalculator.MainActivity.testing(MainActivity.java:60)
I have tried initializing in different ways but can't resolve the error.
The main problem here is that your activity cannot be referenced like this:
ma = new MainActivity();
usedCards = ma.getPlayerCardContents();
Want you can do is start the Class on the Main Activity
CardHandling ch = new CardHandling();
ch.usedCard = getPlayerCardContents();
MainActivity extends AppCompatActivity that means that your activity is not an ordinary object

Text file not found android studio? [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
I'm trying to build a simple app for Android can't figure out why my app keeps crashing I have traced it down to this line of code
<code>WG.setRandomWord(words.get(rand.nextInt(words.size())));</code>
I have check my logcat and it showing that my word file is not even being detected com.sagproductions.gamertaggenerator W/System.err: java.io.FileNotFoundException: words.txt: open failed: ENOENT (No such file or directory) but I have my file word file in the document structure.
for more context here is my code:
JAVA wordGenerator
package com.sagproductions.gamertaggenerator;
public class WordGenerator {
private String mRandomWord;
private int mRandomNum;
public WordGenerator(String randomWord, int randomNum){
mRandomNum=randomNum;
mRandomWord=randomWord;
}
public int getRandomNum(){
return mRandomNum;
}
public void setRandomNum(int randomNum){
mRandomNum=randomNum;
}
public String getRandomWord(){
return mRandomWord;
}
public void setRandomWord(String randomWord){
mRandomWord=randomWord;
}
}
Java MainActivity
package com.sagproductions.gamertaggenerator;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.lang.String;
import java.util.ArrayList;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
WordGenerator WG;
private Button mSingleWordGenerator;
private Button mTwoWordGenerator;
private Button mThreeWordGenerator;
private EditText editText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSingleWordGenerator = (Button)findViewById(R.id.button);
mSingleWordGenerator.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
generateWord();
editText=(EditText)findViewById(R.id.editText);
editText.setText(WG.getRandomWord(),TextView.BufferType.EDITABLE);
}
});
mTwoWordGenerator = (Button)findViewById(R.id.button2);
mTwoWordGenerator.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
mThreeWordGenerator = (Button)findViewById(R.id.button3);
mThreeWordGenerator.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
}
public void generateWord(){
final File file = new File("words.txt");
ArrayList<String> words= new ArrayList<String>();
Random rand=new Random();
try(final Scanner scanner=new Scanner(file)){
while(scanner.hasNextLine()){
String line = scanner.nextLine();
words.add(line);
}
}catch(FileNotFoundException e) {
e.printStackTrace();
}
WG.setRandomWord(words.get(rand.nextInt(words.size())));
}
}
The WG field is never initialized, so it's null. So you're probably getting a NullPointerException when you call that method. You should initialize it somewhere, perhaps when you declare it (so WordGenerator WG; would be replaced by something like WordGenerator WG = new WordGenerator(INITIAL_RANDOM_WORD, INITIAL_RANDOM_VALUE);, where INITIAL_RANDOM_WORD and INITIAL_RANDOM_VALUE are some values you define elsewhere).
Edit: It seems that that line is causing the problem because words.size() is 0, which is because of the FileNotFoundException. The correct way to read that file will depend on where you're putting it. See the answers to this question (and the pages they link to) for different ways to correctly read text files in Android.

At what part of the lifecycle should you initialize objects in a fragment used by a service?

I'm working on an Android app so I can learn mobile dev and I'm stuck with this problem.
Basically in my SampleFragment class I have an adapter called mAdapter and when my TestService gets my data objects and updates my dataObjects arrayList and notifies the adapter that the data has changed the adapter isn't initialized and is null at the time. Is it a thread issue or is it associated with the fragment lifecycle?
SampleFragment.java
import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
public class SampleFragment extends Fragment {
private static final int SEND_DELAY = 1500;
private String userName, sEventId;
private EditText etMessage;
private ImageButton btSend;
private Context applicationContext;
private View view;
private Handler handler = new Handler();
private ArrayList<Message> dataObjects = new ArrayList<>();
private MessageListAdapter mAdapter;
private Runnable initMessageAdapter = new Runnable() {
#Override
public void run() {
initMessageAdapter();
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String eventName = CurrentActiveEvent.getInstance().getEventName();
Activity activity = getActivity();
activity.setTitle(eventName);
mAdapter = new MessageListAdapter(context, userName, dataObjects);
CurrentActiveUser currentUser = CurrentActiveUser.getInstance();
userName = currentUser.getUsername();
Intent intent = new Intent(activity, TestService.class);
activity.startService(intent);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_messaging, container, false);
applicationContext = getActivity();
sEventId = CurrentActiveEvent.getInstance().getEventID();
btSend = (ImageButton) view.findViewById(R.id.btSend);
handler.post(initMessageAdapter);
btSend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
handler.post(new Runnable() {
#Override
public void run() {
saveMessage(body);
}
});
}
});
return view;
}
// Setup message field and posting
private void initMessageAdapter() {
etMessage = (EditText) view.findViewById(R.id.etMessage);
ListView lvChat = (ListView) view.findViewById(R.id.lvChat);
lvChat.setAdapter(mAdapter);
}
public void updatedataObjects(List<objs> newdataObjects){
this.dataObjects.clear();
this.dataObjects.addAll(newdataObjects);
mAdapter.notifyDataSetChanged();
}
}
TestService.java
import android.app.IntentService;
import android.content.Intent;
import java.util.Collections;
import java.util.List;
public class TestService extends IntentService {
private static final int MAX_RESULTS = 50;
private static final String CLASS_NAME = TestService.class.getSimpleName();
private final String sEventId = CurrentActiveEvent.getInstance().getEventID();
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*/
public TestService() {
super(CLASS_NAME);
}
#Override
#SuppressWarnings("unchecked")
protected void onHandleIntent(Intent intent) {
if (NetworkState.isConnected(getApplicationContext())) {
Query query = new Query(Data.class);
query.whereEqualTo(Events.ID, sEventId);
query.orderByDESC(Data.CREATED_AT);
query.setLimit(MAX_RESULTS);
List objs = queryDB(query, Data.class.getSimpleName());
if (objs != null) {
Collections.reverse(objs);
new SampleFragment().updateMessages(objs);
}
}
}
}
Your problem comes from this line:
new SampleFragment().updateMessages(objs);
You are creating a new instance of your fragment inside your service. Since you are not attaching the fragment anywhere, it's lifecycle is not started and the onCreate() method is never called, which results in the NullPointerException.
IntentServices are great for executing tasks on a background thread, but they are components, that are meant to be separated from the UI - related components, like Activities and Fragments. You should never have direct communication between an IntentService and a Fragment or Activity. If you need to return a result from your IntentService, you should consider using the LocalBroadcastManager. It will fire an intent, containing the result, and you can register receivers to intercept it.
There are also other options, like Bound Services - they are created to provide an interface for their clients, and you can use this to return your result. But bear in mind, that, unlike IntentService they don't work in a background thread by default.
Since you are trying to work with a database, I recommend you take a look and the ContentProvider and ContentResolver classes. They are the recommended way of working with DBs in Android and come with loads of neat stuff.

Is it possible to display an overlay item on Google Maps when a marker is tapped?

I already made a simple android application, which I also have integrated Google Maps in it..
It is also capable of connecting to MySQL (localhost) to display my desired places using longitude and latitude values..
My question is, is it possible to make another overlay item above Google Maps when a marker is clicked (just like what happens in foursquare)?
To be specific, i want to display a text that contains the name of a place.
Heres my class of displaying the overlay items.
I made an onTap method, but it display a dialog box, I want to display a simple text box that shows the name of the place.
package finddroid.map;
import java.util.ArrayList;
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.text.TextPaint;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapView;
import com.google.android.maps.OverlayItem;
public class CustomItemizedOverlay extends ItemizedOverlay<OverlayItem>
{
private int markerHeight;
private ArrayList<OverlayItem> mapOverlays = new ArrayList<OverlayItem>();
private Context context;
public CustomItemizedOverlay(Drawable defaultMarker)
{
super(boundCenterBottom(defaultMarker));
markerHeight = ((BitmapDrawable) defaultMarker).getBitmap().getHeight();
populate();
}
public CustomItemizedOverlay(Drawable defaultMarker, Context context)
{
this(defaultMarker);
this.context = context;
}
#Override
protected OverlayItem createItem(int i)
{
return mapOverlays.get(i);
}
#Override
public int size()
{
return mapOverlays.size();
}
#Override
//Event when a place is tapped
protected boolean onTap(int index)
{
OverlayItem item = mapOverlays.get(index);
AlertDialog.Builder dialog = new AlertDialog.Builder(context);
dialog.setTitle(item.getTitle());
dialog.setMessage(item.getSnippet());
dialog.show();
return true;
}
public void addOverlay(OverlayItem overlay)
{
mapOverlays.add(overlay);
this.populate();
}
}
Have a look at this project - balloon itemized overlay. It is using own class extending FrameLayout to show balloons.
So if you want to modify your code put this into your onTap method to display a TextView above taped item
TextView text = new TextView(context);
text.setText(item.getTitle());
MapView.LayoutParams params = new MapView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT, item.getPoint(), MapView.LayoutParams.BOTTOM_CENTER);
params.mode = MapView.LayoutParams.MODE_MAP;
mMapView.addView(text, params);
I think this code is simple and easy to understand and you can improve it accordingly to your needs. To make it work you have to pass instance of MapView to constructor of your overlay and save it to private variable mMapView.
private MapVeiw mMapView;
public CustomItemizedOverlay(Drawable defaultMarker, Context context, MapView mapView) {
this(defaultMarker);
this.context = context;
this.mMapView = mapView;
}
And don't forget to add MapView as one of parameters when you call new CustomItemizedOverlay().

Android : Hello, Views > Google Map View Tuorial

I'm trying to complete the Android MapView tutorial # www.developer.android.com/resources/tutorials/views/hello-mapview.html
I think I've done the entire thing correctly but I'm getting an error message in Eclipse. I'm sure why. The problematic line of code is
private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
I'm relatively new to Java but I've gone through the forums of different things and I really have no idea on this one. I've [attached][2] a screen shot of the development environment - hopefully it wont be anything too obvious or hard to fix either!
http://www.limedomains.com/files/download/34780?dirname=&file_name=hellogooglemaps.jpg
Cheers
Tom :)
** As requested heres the source code and the screenshot link is updated to something that works**
package com.example.hellogooglemaps;
import java.util.ArrayList;
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.drawable.Drawable;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
public class HelloItemizedOverlay extends ItemizedOverlay{
public HelloItemizedOverlay(Drawable defaultMarker) {
super(boundCenterBottom(defaultMarker));
}
#Override
protected OverlayItem createItem(int i) {
return mOverlays.get(i);
}
public void addOverlay(OverlayItem overlay) {
mOverlays.add(overlay);
populate();
}
#Override
public int size() {
return mOverlays.size();
}
public HelloItemizedOverlay(Drawable defaultMarker, Context context) {
super(defaultMarker);
mContext = context;
}
#Override
protected boolean onTap(int index) {
OverlayItem item = mOverlays.get(index);
AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
dialog.setTitle(item.getTitle());
dialog.setMessage(item.getSnippet());
dialog.show();
return true;
}
}
You need to declare the ArrayList inside the class, not outside, like this:
public class HelloItemizedOverlay extends ItemizedOverlay {
private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
}
Your screenshot is impossible to read.. please copy/paste what the logcat says...
For my personnal use, i use this code: List mapOverlays;

Categories