This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 8 years ago.
I created a layout named activity_category and activity named CategoryActivity the code of which is as follows
public class CategoryActivity extends Activity {
private LazyItemLoadAdapter adapter;
private int[] selectionId;
private Item[] item_data;
private GridView grid;
private TextView textview;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.activity_category);
ActionBarUtils.setActionBar(this);
String id=getIntent().getExtras().getString("id");
try{
AsyncData data=new AsyncData();
data.execute(Constants.SERVER+"cat_adlist.php?id="+id);
grid = (GridView) findViewById(R.id.gridViewAllItems);
}catch(NotFoundException n){
}
}
private class AsyncData extends AsyncTask<String, Void, Item[]>{
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
setProgressBarIndeterminateVisibility(true);
}
#Override
protected Item[] doInBackground(String... params) {
String str=null;
try {
str = CustomHttpClient
.executeHttpGet(params[0]);
Log.i("Category Data", str);
JSONArray array = new JSONArray(str);
item_data = new Item[array.length()];
selectionId = new int[array.length()];
for (int i = 0; i < item_data.length; i++) {
JSONObject jdata = array.getJSONObject(i);
String path = Constants.THUMBS
+ jdata.getString("name");
int itemid = jdata.getInt("id");
item_data[i] = new Item(itemid, path, jdata.getString("title"),
jdata.getString("price"));
selectionId[i] = jdata.getInt("subcategory_id");// change the
// field name
// here
}
}catch(JSONException j){
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return item_data;
}
#Override
protected void onPostExecute(Item[] result) {
adapter = new LazyItemLoadAdapter(CategoryActivity.this, R.layout.text_below_images, result);
grid.setAdapter(adapter);
if (result.length == 0) {
grid.setVisibility(View.GONE);
textview.setVisibility(View.VISIBLE);
} else {
grid.setVisibility(View.VISIBLE);
textview.setVisibility(View.GONE);
}
TextView numResults=(TextView) findViewById(R.id.textView2);
numResults.setText("Found "+String.valueOf(result.length)+" results");
setProgressBarIndeterminateVisibility(false);
super.onPostExecute(result);
}
}
}
The logcat is as follows -
05-07 17:09:58.340: E/AndroidRuntime(2242): FATAL EXCEPTION: main
05-07 17:09:58.340: E/AndroidRuntime(2242): Process: com.opaxlabs.salepurchase, PID: 2242
05-07 17:09:58.340: E/AndroidRuntime(2242): java.lang.NullPointerException
05-07 17:09:58.340: E/AndroidRuntime(2242): at com.opaxlabs.salepurchase.CategoryActivity$AsyncData.onPostExecute(CategoryActivity.java:115)
05-07 17:09:58.340: E/AndroidRuntime(2242): at com.opaxlabs.salepurchase.CategoryActivity$AsyncData.onPostExecute(CategoryActivity.java:1)
05-07 17:09:58.340: E/AndroidRuntime(2242): at android.os.AsyncTask.finish(AsyncTask.java:632)
05-07 17:09:58.340: E/AndroidRuntime(2242): at android.os.AsyncTask.access$600(AsyncTask.java:177)
05-07 17:09:58.340: E/AndroidRuntime(2242): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
05-07 17:09:58.340: E/AndroidRuntime(2242): at android.os.Handler.dispatchMessage(Handler.java:102)
05-07 17:09:58.340: E/AndroidRuntime(2242): at android.os.Looper.loop(Looper.java:136)
05-07 17:09:58.340: E/AndroidRuntime(2242): at android.app.ActivityThread.main(ActivityThread.java:5017)
05-07 17:09:58.340: E/AndroidRuntime(2242): at java.lang.reflect.Method.invokeNative(Native Method)
05-07 17:09:58.340: E/AndroidRuntime(2242): at java.lang.reflect.Method.invoke(Method.java:515)
05-07 17:09:58.340: E/AndroidRuntime(2242): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
05-07 17:09:58.340: E/AndroidRuntime(2242): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
05-07 17:09:58.340: E/AndroidRuntime(2242): at dalvik.system.NativeStart.main(Native Method)
As you can see I am getting a null pointer exception. initially it was because I was using a wrong layout but I have corrected that but the problem persists. Please help me with your suggestions. Thanks in advance.
You forget to initialize your TextView textview which is in your onPostExecute method.
#Override
protected void onPostExecute(Item[] result) {
TextView textview =(TextView) findViewById(R.id.textView2);
adapter = new LazyItemLoadAdapter(CategoryActivity.this, R.layout.text_below_images, result);
grid.setAdapter(adapter);
if (result.length == 0) {
grid.setVisibility(View.GONE);
textview.setVisibility(View.VISIBLE);
} else {
grid.setVisibility(View.VISIBLE);
textview.setVisibility(View.GONE);
}
TextView numResults=(TextView) findViewById(R.id.textView2);
numResults.setText("Found "+String.valueOf(result.length)+" results");
setProgressBarIndeterminateVisibility(false);
super.onPostExecute(result);
}
First of all the best practice which I think you should follow is to organise your code in blocks. Initialise all your views after setContentView() no matter when you are using them. If you start doing this you won't have exceptions thrown like this one which you have.
The problem in your code is that you are not initialising your textView variable and using it in your onPostExecute() method of AsyncTask. Your onCreate should look like this:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.activity_category);
grid = (GridView) findViewById(R.id.gridViewAllItems);
textview = (TextView) findViewById(R.id.myTextView);
numResults = (TextView) findViewById(R.id.textView2);
// Start your AsyncTask here ...
}
Related
I am currently creating a Android GoogleMaps app and have stored a list of Locations on a database on an online server. I'm pulling them through successfully and now I want to use the Actionbar searchview to create a listview that the user can search and it will change the currently loaded data to only show the ones linked to the currently selected Location.
However I am coming across the error of cannot be cast to android.content.Context when trying to put the arraylist into the adapter after changing the ListViewAdapter code to be a runnable due to where I am calling it. My main activity code is as follows:
TownSelector ts;
ListView townList;
ListViewAdapter townAdapter; <---set variable for adapter here
String[] townID;
String[] townName;
ArrayList<TownSelector> arraylist = new ArrayList<TownSelector>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//setContentView(R.layout.search);
setUpMapIfNeeded();
// Hashmap for ListView
locationList = new ArrayList<HashMap<String, String>>();
// Locate the ListView in listview_main.xml
townList = (ListView) findViewById(R.id.listview);
}
class LoadAllInfo extends AsyncTask<String, String, String> {
protected String doInBackground(String... args) {
// Building Parameters
List<NameValuePair> paramsLocations = new ArrayList<NameValuePair>();
// getting JSON string from URL
JSONObject jsonLocations = jParser.makeHttpRequest(url_all_locations, "GET", paramsLocations);
//Get all offer
if(jsonLocations != null)
{
// Check your log cat for JSON reponse
Log.d("All Locations: ", jsonLocations.toString());
try {
// Checking for SUCCESS TAG
int success = jsonLocations.getInt(TAG_SUCCESS);
if (success == 1) {
// products found
// Getting Array of Offers
locations = jsonLocations.getJSONArray(TAG_LOCATIONS);
// looping through All Offers
for (int i = 0; i < locations.length(); i++) {
JSONObject c = locations.getJSONObject(i);
// Storing each json item in variable
String id = c.getString(TAG_LID);
String locationName = c.getString(TAG_LNAME);
// creating new HashMap
HashMap<String, String> locationsListMap = new HashMap<String, String>();
// adding each child node to HashMap key => value
locationsListMap.put(TAG_LID, id);
locationsListMap.put(TAG_LNAME, locationName);
// adding HashList to ArrayList
locationList.add(locationsListMap);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
return null;
}
protected void onPostExecute(String file_url) {
// dismiss the dialog after getting all products
pDialog.dismiss();
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
/**
* Updating parsed JSON data into map marker
* */
//TODO setMapMarkers
townID = new String[locationList.size()];
townName = new String[locationList.size()];
for(int l = 0; l <= (locationList.size() - 1); l++)
{
Log.d("Hello", "location loop");
Log.d("Hello", locationList.get(l).toString().split("Location_ID=")[1].split(",")[0]);
townID[l] = locationList.get(l).toString().split("Location_ID=")[1].split(",")[0];
Log.d("Hello", locationList.get(l).toString().split("Location_Name=")[1].split(",")[0].replace("}",""));
townName[l] = locationList.get(l).toString().split("Location_Name=")[1].split(",")[0].replace("}","");
}
for (int i = 0; i < townID.length; i++)
{
ts = new TownSelector(townID[i], townName[i]);
// Binds all strings into an array
arraylist.add(ts);
}
// Pass results to ListViewAdapter Class
townAdapter = new ListViewAdapter(this, arraylist); <--Create new instant of adapter here
// Binds the Adapter to the ListView
townList.setAdapter(townAdapter); //This is the line that causes a crash
}
});
}
}
ListViewAdapter code:
// Declare Variables
Context mContext;
LayoutInflater inflater;
private List<TownSelector> locationlist = null;
private ArrayList<TownSelector> arraylist;
public ListViewAdapter(Runnable runnable, List<TownSelector> locationlist) {
mContext = (Context) runnable;
this.locationlist = locationlist;
inflater = LayoutInflater.from(mContext);
this.arraylist = new ArrayList<TownSelector>();
this.arraylist.addAll(locationlist);
}
I changed the ListViewAdapter code to the what is below after finding this stackflow question android callback fails in fragment fails cannot be cast to android.content.Context
public ListViewAdapter(Context context,Runnable runnable, List<TownSelector> locationlist) {
mContext = context;
this.runnable = runnable;
this.locationlist = locationlist;
inflater = LayoutInflater.from(mContext);
this.arraylist = new ArrayList<TownSelector>();
this.arraylist.addAll(locationlist);
}
error callstack:
09-22 03:58:03.467: E/AndroidRuntime(15586): FATAL EXCEPTION: main
09-22 03:58:03.467: E/AndroidRuntime(15586): Process: biz.nickbullcomputing.bevnav, PID: 15586
09-22 03:58:03.467: E/AndroidRuntime(15586): java.lang.ClassCastException: biz.nickbullcomputing.bevnav.MainActivity$LoadAllInfo$1 cannot be cast to android.content.Context
09-22 03:58:03.467: E/AndroidRuntime(15586): at biz.nickbullcomputing.bevnav.ListViewAdapter.<init>(ListViewAdapter.java:25)
09-22 03:58:03.467: E/AndroidRuntime(15586): at biz.nickbullcomputing.bevnav.MainActivity$LoadAllInfo$1.run(MainActivity.java:409)
09-22 03:58:03.467: E/AndroidRuntime(15586): at android.app.Activity.runOnUiThread(Activity.java:4794)
09-22 03:58:03.467: E/AndroidRuntime(15586): at biz.nickbullcomputing.bevnav.MainActivity$LoadAllInfo.onPostExecute(MainActivity.java:376)
09-22 03:58:03.467: E/AndroidRuntime(15586): at biz.nickbullcomputing.bevnav.MainActivity$LoadAllInfo.onPostExecute(MainActivity.java:1)
09-22 03:58:03.467: E/AndroidRuntime(15586): at android.os.AsyncTask.finish(AsyncTask.java:632)
09-22 03:58:03.467: E/AndroidRuntime(15586): at android.os.AsyncTask.access$600(AsyncTask.java:177)
09-22 03:58:03.467: E/AndroidRuntime(15586): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
09-22 03:58:03.467: E/AndroidRuntime(15586): at android.os.Handler.dispatchMessage(Handler.java:102)
09-22 03:58:03.467: E/AndroidRuntime(15586): at android.os.Looper.loop(Looper.java:157)
09-22 03:58:03.467: E/AndroidRuntime(15586): at android.app.ActivityThread.main(ActivityThread.java:5867)
09-22 03:58:03.467: E/AndroidRuntime(15586): at java.lang.reflect.Method.invokeNative(Native Method)
09-22 03:58:03.467: E/AndroidRuntime(15586): at java.lang.reflect.Method.invoke(Method.java:515)
09-22 03:58:03.467: E/AndroidRuntime(15586): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
09-22 03:58:03.467: E/AndroidRuntime(15586): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:674)
09-22 03:58:03.467: E/AndroidRuntime(15586): at dalvik.system.NativeStart.main(Native Method)
this part in your asyncTask townAdapter = new ListViewAdapter(this, arraylist); is not correct. your editor should have shown error. you need to pass YourActivityName.this just this is sending LoadAllInfo as context which is wrong
I would like to update my Listview in a fragmen in a onPostExecute() separate class.
The first initialization of the the Listview doas work, but wehe I call createList() again, the App crashes (NullPointerException)
Any Idea?
Main_Fragment:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View fragmentView = inflater.inflate(R.layout.main_fragment, container, false);
StartSocketService = (Button) fragmentView.findViewById(R.id.start_socketservice);
StartSocketService.setOnClickListener(this);
StopSocketService = (Button) fragmentView.findViewById(R.id.stop_socketservice);
StopSocketService.setOnClickListener(this);
listview = (ListView) fragmentView.findViewById(R.id.listView1);
createList();
return fragmentView;
}
public void createList(){
//Reading Server IPs from SharedPreferences and put them to ListView
SharedPreferences settings = getActivity().getSharedPreferences("Found_Devices", 0);
for (int i = 0; i < 255; i++) {
if ((settings.getString("Server"+i,null)) != null) {
serverList.add(settings.getString("Server"+i, null));
Log.v("Reading IP: " +settings.getString("Server"+i, null), " from SraredPreferrences at pos.: "+i );
}
}
//Initializing listView
final StableArrayAdapter adapter = new StableArrayAdapter(getActivity(),android.R.layout.simple_list_item_1, serverList);
listview.setAdapter(adapter);
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
#Override
public void onItemClick(AdapterView<?> parent, final View view, int position, long id) {
final String item = (String) parent.getItemAtPosition(position);
view.animate().setDuration(2000).alpha(0).withEndAction(new Runnable() {
#Override
public void run() {
serverList.remove(item);
adapter.notifyDataSetChanged();
view.setAlpha(1);
}
});
}
});
}
Some class:
async_cient = new AsyncTask<Void, Void, Void>() {
...
protected void onPostExecute(Void result) {
Toast.makeText(mContext, "Scan Finished", Toast.LENGTH_SHORT).show();
Main_Fragment cList = new Main_Fragment();
cList.createList();
super.onPostExecute(result);
}
};
Log:
07-29 14:42:46.428 3382-3382/de.liquidbeam.LED.control D/AndroidRuntime﹕ Shutting down VM
07-29 14:42:46.428 3382-3382/de.liquidbeam.LED.control W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x41549ba8)
07-29 14:42:46.438 3382-3382/de.liquidbeam.LED.control E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: de.liquidbeam.LED.control, PID: 3382
java.lang.NullPointerException
at de.liquidbeam.LED.control.fragments.Main_Fragment.createList(Main_Fragment.java:56)
at de.liquidbeam.LED.control.background.UDP_Discover$1.onPostExecute(UDP_Discover.java:94)
at de.liquidbeam.LED.control.background.UDP_Discover$1.onPostExecute(UDP_Discover.java:57)
at android.os.AsyncTask.finish(AsyncTask.java:632)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
07-29 14:47:46.591 3382-3382/de.liquidbeam.LED.control I/Process﹕ Sending signal. PID: 3382 SIG: 9
Lines:
56 : SharedPreferences settings = getActivity().getSharedPreferences("Found_Devices", 0);
94 : cList.createList();
57: async_cient = new AsyncTask<Void, Void, Void>() {
You creating a new instance of your fragment with no context (activity) to run in. So
the line
SharedPreferences settings = getActivity().getSharedPreferences("Found_Devices", 0);
Tries to get his activity but there is no activity where the fragment lives in ;)
I know this answer is probably simple but i cannot figure it out. I am modifying example code for a project and keep getting a ClassCastException when i try to launch the app. Says that ListActivityFragment cannot be cast to android.app.Activity. What im not understanding(which is probably the simple part) is why its trying to cast it onto an activity when my main is a fragmentactivity. I know the code is rough, still trying to finish it up but cant get past this.
FragmentActivity
public class MainActivity extends FragmentActivity {
private boolean isLargeScreen = true;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (findViewById(R.id.normal_screen_layout) != null) {
isLargeScreen = false;
ListActivityFragment listActivityFragment = new ListActivityFragment();
listActivityFragment.setArguments(getIntent().getExtras());
getSupportFragmentManager().beginTransaction()
.add(R.id.normal_screen_layout, listActivityFragment)
.commit();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.addItem:
ListActivityFragment newFragment = new ListActivityFragment();
FragmentTransaction transaction = getSupportFragmentManager()
.beginTransaction();
transaction.replace(R.id.normal_screen_layout, newFragment);
transaction.addToBackStack(null);
transaction.commit();
break;
default:
return super.onOptionsItemSelected(item);
}
return true;
}
}
}
ListActivity
public class ListActivityFragment extends ListFragment implements
OnClickListener {
private ArrayList<String> items = new ArrayList<String>();
private ListView listView;
private View outerView;
private Button deleteButton;
private ListActivityListener listener;
public interface ListActivityListener {
public void meetingAdded();
}
public ListActivityFragment() {
}
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
listener = (ListActivityListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnHeadlineSelectedListener");
}
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
outerView = inflater.inflate(R.layout.list_of_meetings, container,
false);
listView = (ListView) outerView.findViewById(R.id.listView1);
deleteButton = (Button) outerView.findViewById(R.id.deleteButton);
createList();
return outerView;
}
public void createList() {
items.clear();
Iterator<Items> iterator = ItemCollection.Instance().iterator();
while (iterator.hasNext()) {
items.add(iterator.next().toString());
}
listView.setAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, items));
}
#Override
public void onClick(DialogInterface arg0, int arg1) {
ListView listView = getListView();
for (int index = 0; index < listView.getChildCount(); index++) {
View viewGroup = listView.getChildAt(index);
CheckBox checkBox = (CheckBox) viewGroup
.findViewById(R.id.itemSelectCheckBox);
if (checkBox.isChecked()) {
TextView textView = (TextView) viewGroup
.findViewById(R.id.productTextView);
int key = (Integer) textView.getTag();
ItemCollection.Instance().delete(key);
}
}
createList();
}
#Override
public void onStart() {
super.onStart();
}
public void onListItemClick(ListView l, View v, int position, long id) {
getListView().setItemChecked(position, true);
}
}
And heres the Logcat
07-15 01:59:50.710: E/AndroidRuntime(878): FATAL EXCEPTION: main
07-15 01:59:50.710: E/AndroidRuntime(878): Process: com.example.assignment5, PID: 878
07-15 01:59:50.710: E/AndroidRuntime(878): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.assignment5/com.example.assignment5.ListActivityFragment}: java.lang.ClassCastException: com.example.assignment5.ListActivityFragment cannot be cast to android.app.Activity
07-15 01:59:50.710: E/AndroidRuntime(878): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2121)
07-15 01:59:50.710: E/AndroidRuntime(878): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
07-15 01:59:50.710: E/AndroidRuntime(878): at android.app.ActivityThread.access$800(ActivityThread.java:135)
07-15 01:59:50.710: E/AndroidRuntime(878): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
07-15 01:59:50.710: E/AndroidRuntime(878): at android.os.Handler.dispatchMessage(Handler.java:102)
07-15 01:59:50.710: E/AndroidRuntime(878): at android.os.Looper.loop(Looper.java:136)
07-15 01:59:50.710: E/AndroidRuntime(878): at android.app.ActivityThread.main(ActivityThread.java:5017)
07-15 01:59:50.710: E/AndroidRuntime(878): at java.lang.reflect.Method.invokeNative(Native Method)
07-15 01:59:50.710: E/AndroidRuntime(878): at java.lang.reflect.Method.invoke(Method.java:515)
07-15 01:59:50.710: E/AndroidRuntime(878): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
07-15 01:59:50.710: E/AndroidRuntime(878): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
07-15 01:59:50.710: E/AndroidRuntime(878): at dalvik.system.NativeStart.main(Native Method)
07-15 01:59:50.710: E/AndroidRuntime(878): Caused by: java.lang.ClassCastException: com.example.assignment5.ListActivityFragment cannot be cast to android.app.Activity
07-15 01:59:50.710: E/AndroidRuntime(878): at android.app.Instrumentation.newActivity(Instrumentation.java:1061)
07-15 01:59:50.710: E/AndroidRuntime(878): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2112)
07-15 01:59:50.710: E/AndroidRuntime(878): ... 11 more
07-15 01:59:51.160: E/NetdConnector(383): NDC Command {65 bandwidth setiquota eth0 9223372036854775807} took too long (1117ms)
Caused by: java.lang.ClassCastException:
com.example.assignment5.ListActivityFragment cannot be cast to
android.app.Activity 07-15 01:59:50.710: E/AndroidRuntime(878):
As the error says -
ListActivityFragment is not an activity. So you are trying to access it just like an activity.
Make sure you haven't declared ListActivityFragment in the manifest. In your manifest if you made an entry for the fragment then that's wrong.
Also make sure that you haven't used startActivity for the fragment. Because this is done for activity class and not for fragment class.
Building on a theme from yesterday...I'm getting an NPE accessing a method in a singleton Application class from within an AlertDialog.
Activity SavedMealsActivity sets OnLongClickListenerSavedMeals as the listener for a series of TextViews in a ScrollView. OnLongClickListenerSavedMeals is defined as a separate class.
OnLongClickListenerSavedMeals displays an AlertDialog which gives the option of going to a different Activity, but it first needs to fire the methods of an Application class which is defined as a singleton (MealTimerApplication). This is the first line of the onClick method (line 25 in the first code sample below), and it throws the NPE because the activity is null at the time.
I've tried passing in the activity from the calling Activity (SavedMealsActivity) but for some reason it's not working as I'd hoped. Any ideas?
OnLongClick listener class - OnLongClickListenerSavedMeals:
public class OnLongClickListenerSavedMeals implements OnLongClickListener {
Context context;
String id;
private Activity activity;
public OnLongClickListenerSavedMeals(Activity activity) {
this.activity = activity;
this.context = activity;
}
#Override
public boolean onLongClick(View view){
// TODO Auto-generated method stub
this.context = context;
id = view.getTag().toString();
final CharSequence[] items = { "Edit", "Delete" };
//Set activity to allow context to be used in the OnClickListener/onClick method below
this.activity = activity;
new AlertDialog.Builder(context).setTitle("Meal Item")
.setItems(items, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
if (item == 0) {
//Set the global meal_id variable and invoke the MealActivity
((MealTimerApplication) activity.getApplication()).setMealId(Long.getLong(id));
Intent myIntent = new Intent(activity.getBaseContext(),MealActivity.class);
activity.startActivityForResult(myIntent, 0);
}
else if (item == 1) {
boolean deleteSuccessful = new TableControllerMeal(context).delete(id);
if (deleteSuccessful){
Toast.makeText(context, "Record was deleted.", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(context, "Unable to delete record.", Toast.LENGTH_SHORT).show();
}
((SavedMealsActivity) context).readRecords();
}
dialog.dismiss();
}
}).show();
return false;
}
Calling Activity - SavedMealsActivity:
public class SavedMealsActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_saved_meals);
//Read saved meal records from the database and display them
readRecords();
}
public void readRecords() {
LinearLayout linearLayoutRecords = (LinearLayout) findViewById(R.id.linearLayoutRecords);
linearLayoutRecords.removeAllViews();
List<meal> meal = new TableControllerMeal(this).read();
if (meal.size() > 0) {
for (meal obj : meal) {
long id = obj.id;
String MealDesc = obj.meal_desc;
int MealMinutes = obj.meal_ready_time;
String textViewContents = MealDesc + " - ready at "
+ Utilities.formatTime(MealMinutes);
TextView textViewItem = new TextView(this);
textViewItem.setPadding(0, 10, 0, 10);
textViewItem.setText(textViewContents);
textViewItem.setTag(Long.toString(id));
textViewItem.setOnLongClickListener(new OnLongClickListenerSavedMeals(this));
linearLayoutRecords.addView(textViewItem);
}
}
else {
TextView Item = new TextView(this);
Item.setPadding(8, 8, 8, 8);
Item.setText("No records yet.");
linearLayoutRecords.addView(Item);
}
}
Application class:
public class MealTimerApplication extends Application {
private static MealTimerApplication singleton;
private long mealId = 0;
// Returns the application instance
public static MealTimerApplication getInstance() {
return singleton;
}
public final void onCreate() {
super.onCreate();
singleton = this;
}
public void setMealId(long mealId) {
this.mealId = mealId;
}
public long getMealId() {
return this.mealId;
}
}
Logcat:
05-28 16:48:03.637: E/AndroidRuntime(4241): java.lang.NullPointerException
05-28 16:48:03.637: E/AndroidRuntime(4241): at com.ian.mealtimer.OnLongClickListenerSavedMeals$1.onClick(OnLongClickListenerSavedMeals.java:39)
05-28 16:48:03.637: E/AndroidRuntime(4241): at com.android.internal.app.AlertController$AlertParams$3.onItemClick(AlertController.java:941)
05-28 16:48:03.637: E/AndroidRuntime(4241): at android.widget.AdapterView.performItemClick(AdapterView.java:299)
05-28 16:48:03.637: E/AndroidRuntime(4241): at android.widget.AbsListView.performItemClick(AbsListView.java:1113)
05-28 16:48:03.637: E/AndroidRuntime(4241): at android.widget.AbsListView$PerformClick.run(AbsListView.java:2904)
05-28 16:48:03.637: E/AndroidRuntime(4241): at android.widget.AbsListView$3.run(AbsListView.java:3638)
05-28 16:48:03.637: E/AndroidRuntime(4241): at android.os.Handler.handleCallback(Handler.java:733)
05-28 16:48:03.637: E/AndroidRuntime(4241): at android.os.Handler.dispatchMessage(Handler.java:95)
05-28 16:48:03.637: E/AndroidRuntime(4241): at android.os.Looper.loop(Looper.java:136)
05-28 16:48:03.637: E/AndroidRuntime(4241): at android.app.ActivityThread.main(ActivityThread.java:5017)
05-28 16:48:03.637: E/AndroidRuntime(4241): at java.lang.reflect.Method.invokeNative(Native Method)
05-28 16:48:03.637: E/AndroidRuntime(4241): at java.lang.reflect.Method.invoke(Method.java:515)
05-28 16:48:03.637: E/AndroidRuntime(4241): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
05-28 16:48:03.637: E/AndroidRuntime(4241): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
05-28 16:48:03.637: E/AndroidRuntime(4241): at dalvik.system.NativeStart.main(Native Method)
You get NPE because of autoboxing. Long.getLong(String) is not what you actually you need, check its description:
Returns the Long value of the system property identified by string.
It definitely returns null in your case. Moreover it returns null reference to Long object, but your MealTimerApplication.setMealId expects argument with primitive type long. Here is the point where auto-boxing implicitly trying to cast your Long object returned by getLong method to the long primitive. But as value was null auto-boxing fails and you get NPE.
You should just use Long.valueOf(String) instead of Long.getLong(String).
My edit text serves as a search box, and I am getting movies from rotten tomatoes API, using the text inside my edit text, problem is. when a space is inserted the application crashes, I am assuming that I need to convert the spaces into +'s, but I have no clue how where to add this code or how exactly, I hope someone here will be able to help me.
this is my code:
private TextView searchBox;
private Button bGo, bCancelAddFromWeb;
private ListView moviesList;
public final static int ACTIVITY_WEB_ADD = 3;
public List<String> movieTitles;
public List<String> movieSynopsis;
public List<String> movieImgUrl;
private ProgressDialog pDialog;
// the Rotten Tomatoes API key
private static final String API_KEY = "8q6wh77s65a54w433cab9rbsq";
// the number of movies to show
private static final int MOVIE_PAGE_LIMIT = 8;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.movie_add_from_web);
InitializeVariables();
}
/*
* Initializing the variables and creating the bridge between the views from
* the xml file and this class
*/
private void InitializeVariables() {
searchBox = (EditText) findViewById(R.id.etSearchBox);
bGo = (Button) findViewById(R.id.bGo);
bCancelAddFromWeb = (Button) findViewById(R.id.bCancelAddFromWeb);
moviesList = (ListView) findViewById(R.id.list_movies);
bGo.setOnClickListener(this);
bCancelAddFromWeb.setOnClickListener(this);
moviesList.setOnItemClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bGo:
new RequestTask()
.execute("http://api.rottentomatoes.com/api/public/v1.0/movies.json?apikey="
+ API_KEY
+ "&q="
+ searchBox.getText()
+ "&page_limit=" + MOVIE_PAGE_LIMIT);
break;
case R.id.bCancelAddFromWeb:
finish();
break;
}
}
private void refreshMoviesList(List<String> movieTitles) {
moviesList.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, movieTitles
.toArray(new String[movieTitles.size()])));
}
private class RequestTask extends AsyncTask<String, String, String> {
// make a request to the specified url
#Override
protected String doInBackground(String... uri) {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
String responseString = null;
try {
// make a HTTP request
response = httpclient.execute(new HttpGet(uri[0]));
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
responseString = out.toString();
} else {
// close connection
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (Exception e) {
Log.d("Test", "Couldn't make a successful request!");
}
return responseString;
}
// if the request above completed successfully, this method will
// automatically run so you can do something with the response
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(MovieAddFromWeb.this);
pDialog.setMessage("Searching...");
pDialog.show();
}
#Override
protected void onPostExecute(String response) {
super.onPostExecute(response);
try {
// convert the String response to a JSON object
JSONObject jsonResponse = new JSONObject(response);
// fetch the array of movies in the response
JSONArray jArray = jsonResponse.getJSONArray("movies");
// add each movie's title to a list
movieTitles = new ArrayList<String>();
// newly added
movieSynopsis = new ArrayList<String>();
movieImgUrl = new ArrayList<String>();
for (int i = 0; i < jArray.length(); i++) {
JSONObject movie = jArray.getJSONObject(i);
movieTitles.add(movie.getString("title"));
movieSynopsis.add(movie.getString("synopsis"));
movieImgUrl.add(movie.getJSONObject("posters").getString(
"profile"));
}
// refresh the ListView
refreshMoviesList(movieTitles);
} catch (JSONException e) {
Log.d("Test", "Couldn't successfully parse the JSON response!");
}
pDialog.dismiss();
}
}
#Override
public void onItemClick(AdapterView<?> av, View view, int position, long id) {
Intent openMovieEditor = new Intent(this, MovieEditor.class);
openMovieEditor.putExtra("movieTitle", movieTitles.get(position));
// newly added
openMovieEditor.putExtra("movieSynopsis", movieSynopsis.get(position));
openMovieEditor.putExtra("movieImgUrl", movieImgUrl.get(position));
openMovieEditor.putExtra("callingActivity", ACTIVITY_WEB_ADD);
startActivityForResult(openMovieEditor, ACTIVITY_WEB_ADD);
}
}
this is the log with the error:
01-14 20:19:19.591: D/Test(907): Couldn't make a successful request!
01-14 20:19:19.690: D/AndroidRuntime(907): Shutting down VM
01-14 20:19:19.700: W/dalvikvm(907): threadid=1: thread exiting with uncaught exception (group=0x40a13300)
01-14 20:19:19.801: E/AndroidRuntime(907): FATAL EXCEPTION: main
01-14 20:19:19.801: E/AndroidRuntime(907): java.lang.NullPointerException
01-14 20:19:19.801: E/AndroidRuntime(907): at org.json.JSONTokener.nextCleanInternal(JSONTokener.java:116)
01-14 20:19:19.801: E/AndroidRuntime(907): at org.json.JSONTokener.nextValue(JSONTokener.java:94)
01-14 20:19:19.801: E/AndroidRuntime(907): at org.json.JSONObject.<init>(JSONObject.java:154)
01-14 20:19:19.801: E/AndroidRuntime(907): at org.json.JSONObject.<init>(JSONObject.java:171)
01-14 20:19:19.801: E/AndroidRuntime(907): at il.jb.projectpart2.MovieAddFromWeb$RequestTask.onPostExecute(MovieAddFromWeb.java:152)
01-14 20:19:19.801: E/AndroidRuntime(907): at il.jb.projectpart2.MovieAddFromWeb$RequestTask.onPostExecute(MovieAddFromWeb.java:1)
01-14 20:19:19.801: E/AndroidRuntime(907): at android.os.AsyncTask.finish(AsyncTask.java:631)
01-14 20:19:19.801: E/AndroidRuntime(907): at android.os.AsyncTask.access$600(AsyncTask.java:177)
01-14 20:19:19.801: E/AndroidRuntime(907): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
01-14 20:19:19.801: E/AndroidRuntime(907): at android.os.Handler.dispatchMessage(Handler.java:99)
01-14 20:19:19.801: E/AndroidRuntime(907): at android.os.Looper.loop(Looper.java:137)
01-14 20:19:19.801: E/AndroidRuntime(907): at android.app.ActivityThread.main(ActivityThread.java:4745)
01-14 20:19:19.801: E/AndroidRuntime(907): at java.lang.reflect.Method.invokeNative(Native Method)
01-14 20:19:19.801: E/AndroidRuntime(907): at java.lang.reflect.Method.invoke(Method.java:511)
01-14 20:19:19.801: E/AndroidRuntime(907): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
01-14 20:19:19.801: E/AndroidRuntime(907): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
01-14 20:19:19.801: E/AndroidRuntime(907): at dalvik.system.NativeStart.main(Native Method)
You should use standard URL encoding as follows:
case R.id.bGo:
new RequestTask()
.execute("http://api.rottentomatoes.com/api/public/v1.0/movies.json?apikey="
+ API_KEY
+ "&q="
+ URLEncoder.encode(searchBox.getText(), "UTF-8")
+ "&page_limit=" + MOVIE_PAGE_LIMIT);
This will replace spaces and all other non-URL-friendly characters with allowed characters (as defined by RFC 1738 and the HTML spec)
Need to see your logcat to make sure that's the actual problem, but from your code it looks like it is at least one of your issues.
Ideally you'd do something like
String search = searchBox.getText();
search = search.replace(" ", "+");
and then use that variable to send to your RequestTask
Source: Android Developers
Conversely, you may be better off doing a full encoding on the string returned instead of just replacing spaces... as other characters will cause you issues as well (?, &, etc)
EDIT: See EJK's answer for the URLEncoding version.