I'm getting NPE when I try to instantiate a class, I already tried using NameOftheClass.this, getApplicationContext(), getApplication(). None of those is working, here is the log:
java.lang.NullPointerException
at br.com.FragmentClientes.<init>(FragmentClientes.java:87)
line 87 is: mRepositorio = new Repositorio(FragmentClientes.this);
And here is the snippet:
public class FragmentClientes extends ActionBarActivity {
private boolean searchCheck;
private List<ClienteModel> clientes = new ArrayList<ClienteModel>();
private ProgressBar progressBar;
private ListView lv;
private ClientViewAdapter ad;
private ClientViewAdapter ads;
private SearchView searchView;
private LinearLayout footerLinearLayout;
private boolean shouldExecuteOnResume;
private Repositorio mRepositorio;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// TODO Auto-generated method stub
setContentView(R.layout.fragment_cliente);
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
SecurePreferences mSessao = new SecurePreferences(FragmentClientes.this, "sessao");
mSessao.put("menuAtual", "Clientes");
lv = (ListView) findViewById(R.id.listaClientes);
}
public FragmentClientes(Integer idViagem) {
clientes = new ArrayList<ClienteModel>();
try {
mRepositorio = new Repositorio(FragmentClientes.this);
List lista = mRepositorio.getClientesViagem(idViagem);
clientes = lista;
ad = new ClientViewAdapter(FragmentClientes.this, this, clientes);
lv.setVerticalFadingEdgeEnabled(true);
lv.setVerticalScrollBarEnabled(true);
lv.setAdapter(ad);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Do not use an activity context inside its constructor, it will now work. Please put all the code from the constructor into a method and call it inside the `onCreate method like this:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// TODO Auto-generated method stub
setContentView(R.layout.fragment_cliente);
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
SecurePreferences mSessao = new SecurePreferences(FragmentClientes.this, "sessao");
mSessao.put("menuAtual", "Clientes");
Integer idViagem = getIntent().getIntExtra(TAG, -1);
init(idViagem);
}
public void init(Integer mId) {
clientes = new ArrayList<ClienteModel>();
try {
mRepositorio = new Repositorio(FragmentClientes.this);
List lista = mRepositorio.getClientesViagem(mId);
clientes = lista;
ad = new ClientViewAdapter(FragmentClientes.this, this, clientes);
lv.setVerticalFadingEdgeEnabled(true);
lv.setVerticalScrollBarEnabled(true);
lv.setAdapter(ad);
} catch (Exception e) {
e.printStackTrace();
}
}
Also, you will need to find another way of passing the integer parameter.
For this, use Intent.putExtra(TAG, idViagem) on the intent which starts the activity and then retrieve the value in the constructor with getIntent().getIntExtra(TAG, -1)
For example if you're starting FragmentClientes activity from another activity:
Intent intent = new Intent(this, FragmentClientes.class);
intent.putExtra("idViagem", int_value_of_id_that_you_passed_through_constructor);
startActivity(intent);
Dont create Parameteriged Activity Constructor
just init your data in Activity Call back methods like onCreate(),onResume()
Start your Activity Using Intent
For more read Activity doc Activity Documnetation
FragmentClientes is an Activity. You should not define a custom counstructor, since the method onCreate behaves as constructor and will be called automatically by the system.
so put you code into onCreate method.
Important: you should never, i mean realy never call new FragmentClientes(1);
It might be because yout ListView is not properly instantiated
private ListView lv;
You never asign (in the code you provided) any instantiation for the object.
Related
I am making a basic app that just reads RSS files from google and displays the headlines in a listview. The problem I am having is that the static ArrayList I am using in an IntentService is empty when I access it after I start the intent for the service. There could be something very basic I am missing here but tit used to work before I added more RSS links to the service. I tried commenting them out to see if there was some sort of overloading somewhere but nothing changed, which I guess means that I changed something else without realizing or remembering it.
Here is my relavent code, the ArrayList I am trying to access is the newsList variable in RSSsearcher. In the past I have logged the string values of the arraylist and confirmed that it was being populated in the RSSsearcher class, but empty in the MainActivity class.
Relevant code:
RSSsearcher:
public class RSSsearcher extends IntentService {
public static ArrayList<NewsCard> newsList = new ArrayList<>();
private static String TAG = "RSS";
public RSSsearcher() {
super("RSSsearcher");
}
#Override
protected void onHandleIntent(#Nullable Intent intent) {
parseNewsLists();
Log.i(TAG,"newsList in onHandleIntent" + newsList);
}
public static ArrayList<NewsCard> getNewsCards() {
return newsList;
}
//helper method to create all the RSSfeed objects
private void parseNewsLists() {
Log.i(TAG, "the service has been started");
//Creating the RSS feed objects
RSSfeed topStories = new RSSfeed("https://news.google.com/news?cf=all&hl=en&pz=1&ned=us&output=rss");
RSSfeed worldNews = new RSSfeed("https://news.google.com/news/rss/headlines/section/topic/WORLD?ned=us&hl=en");
RSSfeed usNews = new RSSfeed("https://news.google.com/news/rss/headlines/section/topic/NATION?ned=us&hl=en");
RSSfeed buisnessNews = new RSSfeed("https://news.google.com/news/rss/headlines/section/topic/BUSINESS?ned=us&hl=en");
RSSfeed technologyNews = new RSSfeed("https://news.google.com/news/rss/headlines/section/topic/TECHNOLOGY?ned=us&hl=en");
RSSfeed entertainmentNews = new RSSfeed("https://news.google.com/news/rss/headlines/section/topic/ENTERTAINMENT?ned=us&hl=en");
RSSfeed sportsNews = new RSSfeed("https://news.google.com/news/rss/headlines/section/topic/SPORTS?ned=us&hl=en");
RSSfeed scienceNews = new RSSfeed("https://news.google.com/news/rss/headlines/section/topic/SCIENCE?ned=us&hl=en");
RSSfeed healthNews = new RSSfeed("https://news.google.com/news/rss/headlines/section/topic/HEALTH?ned=us&hl=en");
try {
//getting RSS feeds
topStories.FileReader();
worldNews.FileReader();
usNews.FileReader();
buisnessNews.FileReader();
technologyNews.FileReader();
entertainmentNews.FileReader();
sportsNews.FileReader();
scienceNews.FileReader();
healthNews.FileReader();
} catch (Exception e) {
Log.i(TAG, Log.getStackTraceString(e));
}
//adding stories to main
newsList.addAll(topStories.getNews());
newsList.addAll(worldNews.getNews());
newsList.addAll(usNews.getNews());
newsList.addAll(buisnessNews.getNews());
newsList.addAll(technologyNews.getNews());
newsList.addAll(entertainmentNews.getNews());
newsList.addAll(sportsNews.getNews());
newsList.addAll(scienceNews.getNews());
newsList.addAll(healthNews.getNews());
}
}
MainActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//TODO remove and have actual tags show up
TagCard onecard = new TagCard("TestCard");
TagCard twocard = new TagCard("TestCard2");
dummyTags.add(onecard);
dummyTags.add(twocard);
mainListView = (ListView) findViewById(R.id.main_content_list);
drawerLayout = (DrawerLayout) findViewById(R.id.main_layout);
tagDrawerList = (ListView) findViewById(R.id.tag_drawer);
//setting an intent for the RSSsearcher to fetch the news
//TODO make this happen every 15 minutes or so
Intent intent = new Intent(this, RSSsearcher.class);
startService(intent);
NewsCard card = new NewsCard("Testing", "linkeroni");
//adding all the NewsCard objects to this classes newsList
newsList.addAll(RSSsearcher.getNewsCards());
MainAdapter adapter = new MainAdapter(this, newsList);
mainListView.setAdapter(adapter);
Log.i(TAG, "This is the array from main activity" + newsList.toString());
actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.open_drawer, R.string.close_drawer){
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
getActionBar().setTitle("Closed");
}
public void onDrawerOpened(View view){
super.onDrawerOpened(view);
getActionBar().setTitle("Open");
}
};
//TODO removed dummytags and add actual tag implementation
tagDrawerList.setAdapter(new TagAdapter(this,dummyTags));
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
}
Thank you in advance!
I think that when you call
newsList.addAll(RSSsearcher.getNewsCards());
The intent is still in execution
I've got 2 activities and a class that extends Application where I'm trying to store global variables with a kind of setter getter functions.
The main activity sets some views and a chart; then calls the second activity which should be setting values to be used afterwards on the previous chart.
Then pressing backbutton and returning to the previous activity onRestart is called and the chart is refreshed.
The problem is I lose my theorically global variables somewhere. Debugging i realized that the functions work perfectly fine while im adding values in the second activity but when I return to the first activity globalXCount returns '0' again. Why is that?
I think im missunderstanding some point regarding lifecycles.
I attach some fragments of the code.
First activity:
public class MainActivity extends Activity {
Global glObj = new Global();
CombinedChart mChart;
private int itemcount;
float displayed;
private final List<String> mMonthList = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
itemcount = ((Global) this.getApplication()).getGlobalXCount();
displayed = itemcount/20;
mChart = (CombinedChart) findViewById(R.id.mchart);
populateHeaderList();
setChartSettings();
Intent intent = new Intent(MainActivity.this, QandA.class);
startActivity(intent);
}
#Override
protected void onRestart() {
super.onRestart();
itemcount = ((Global) this.getApplication()).getGlobalXCount();
displayed = itemcount/20;
populateHeaderList();
setChartSettings();
}
Second activity:
public class QandA extends Activity {
Global glObj = new Global();
ViewFlipper flipper;
private float lastX;
...
}else{
//TODO If all information if correctly filled
trainedmins = et1.getText().toString();
localLineValue = Integer.parseInt(trainedmins) * Integer.parseInt(statusQ1);
//Add values to lines
glObj.setLineXvalues(localLineValue);
// TODO Add new Bar value //
//Add 1 more value to count
glObj.addGlobalXCount();
}
...
Global class:
public class Global extends Application {
//TODO
public Integer globalXCount;
private List<Integer> lineXvalues = new ArrayList<>();
private List<Integer> barXvalues = new ArrayList<>();
//////
public Integer getGlobalXCount() {
if (this.globalXCount == null){
this.globalXCount = 0;
return this.globalXCount;
}else{
return this.globalXCount;
}
}
public void addGlobalXCount() {
if (this.globalXCount == null){
this.globalXCount = 0;
}else{
this.globalXCount = this.globalXCount + 1;
}
}
Thanks in advance.
First of all, register your custom Application context in AndroidManifest.xml within the <application>-tag.
<application
android:name="<your_package>.Global" ...>
Access the global application context within your activities like this:
Global glObj = (Global) getApplicationContext();
glObj.addGlobalXCount();
Do not create a new instance with new! Always retrieve the instance via getApplicationContext().
Furthermore, I would suggest you to initialize your class field glObj within the onCreate()-method of your Activities.
I want to create a connection through socket but I'm having trouble with the graphic of my App:
This is my activity:
public class Messaggi2 extends ActionBarActivity{
LinearLayout mLayout;
ScrollView scroll;
EditText scriviMessaggi;
Button invia;
Socket connessione;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.messaggi2);
mLayout = (LinearLayout) findViewById(R.id.LinearScrollLayout);
scroll = (ScrollView) findViewById(R.id.scrollView2);
scriviMessaggi = (EditText) findViewById(R.id.Scrivi);
invia = (Button) findViewById(R.id.Invia);
LavoraDietro asd = new LavoraDietro(connessione);
asd.execute();
}
private TextView createNewTextView(String text) {
final LinearLayout.LayoutParams lparams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); final TextView textView = new TextView(this);
textView.setLayoutParams(lparams);
textView.setText(text);
textView.setBackgroundResource(R.drawable.balloon_broadcast_incoming_pressed);
return textView;
}
private TextView createNewTextViewSent(String text) {
final LinearLayout.LayoutParams llparams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
llparams.gravity = Gravity.RIGHT;
final TextView textViewSent = new TextView(this);
textViewSent.setLayoutParams(llparams);
textViewSent.setText(text);
textViewSent.setBackgroundResource(R.drawable.balloon_outgoing_normal);
return textViewSent;
}
public void AggiungiTextALlayout(String messaggio){
mLayout.addView(createNewTextView(messaggio));
aggiornaScroll();
}
public void AggiungiTextInviatoALlayout(String messaggio){
mLayout.addView(createNewTextViewSent(messaggio));
aggiornaScroll();
}
public void aggiornaScroll(){
scroll.post(new Runnable() {
#Override
public void run() {
scroll.fullScroll(View.FOCUS_DOWN);
}
});
}
}
This is my AsynTask class:
public class LavoraDietro extends AsyncTask<Void, Void, Socket> {
Socket connessione;
boolean vediSeDeviPartire;
Messaggi2 mess = new Messaggi2();
public LavoraDietro(Socket connessione){
this.connessione = connessione;
}
#Override
protected Socket doInBackground(Void... params){
try {
InetAddress local = InetAddress.getByName("192.168.1.71");
connessione = new Socket(local , 7000);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
return null;
}catch(Exception e){
e.printStackTrace();
}
return connessione;
}
#Override
protected void onPostExecute(Socket result) {
super.onPostExecute(result);
if(result != null){
vediSeDeviPartire = true;
mess.AggiungiTextALlayout("Sono connesso al server");
mess.AggiungiTextALlayout("I canali sono aperi..");
}
else{
mess.AggiungiTextALlayout("ERRORE CONNESSIONE AL SERVER ");
}
}
}
Using this code when I start my app the connection is established and then it crashes. What I see on my Logcat is this Exception:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
So I tried to delete the content of my onPostExecute and everything works perfect. So the mistake is to try to call the method AggiungiTextAlLayout on my AsyncTask class.
Can someone help me with this? Can someone suggest me something? I'm new in this field so I know that this is a stupid thing but I need help.
Thanks guys in advance
EDITED WITH THE SOLUTION
Thanks to Ataulm I got the problem and I solved it I changed the costructor of my LavoraDietro class (unfortunatly I can't change the name of variables and classes in English. But next time I ll use english Name of course )
LavoraDietro Class
public class LavoraDietro extends AsyncTask<Void, Void, Socket> {
Socket connessione;
boolean vediSeDeviPartire;
Messaggi2 action;
public LavoraDietro(Socket connessione, Messaggi2 action){
this.connessione = connessione;
this.action = action;
}
#Override
protected Socket doInBackground(Void... params){
try {
InetAddress local = InetAddress.getByName("192.168.1.71");
connessione = new Socket(local , 7000);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
return null;
}catch(Exception e){
e.printStackTrace();
}
return connessione;
}
#Override
protected void onPostExecute(Socket result) {
super.onPostExecute(result);
if(result != null){
vediSeDeviPartire = true;
action.AggiungiTextALlayout("Sono connesso al server");
action.AggiungiTextALlayout("I canali sono aperi..");
}
else{
action.AggiungiTextALlayout("ERRORE CONNESSIONE AL SERVER ");
}
}
}
And in the Messaggi2 class I changed the call of the constructor in this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.messaggi2);
mLayout = (LinearLayout) findViewById(R.id.LinearScrollLayout);
scroll = (ScrollView) findViewById(R.id.scrollView2);
scriviMessaggi = (EditText) findViewById(R.id.Scrivi);
invia = (Button) findViewById(R.id.Invia);
LavoraDietro asd = new LavoraDietro(connessione, this);
asd.execute();
Your AsyncTask has a reference to mess which is an object of type Messaggi2.
Messaggi2 is a subclass of Activity. You attempt, inside your AsyncTask, to create a new instance of that class.
The Android system has no awareness of this object; it has called none of the life cycle methods, such as onCreate() where the activity's layout would typically be inflated. This means that none of your views are inflated nor even initialised.
When you call mess.AggiungiTextALlayout("Sono connesso al server");, mLayout is null.
The NPE you see may likely not even be this one.
TL;DR: don't instantiate your Activity objects like Java objects; use them as specified within the Android framework.
I suspect you have this Activity starting correctly somewhere. The mistake is that you've not associated that activity with your Asynctask. When you create LavoraDietro, you pass a reference to the Socket in the constructor; you can also pass a reference to your activity, and assign that to the mess field, instead of calling new Messaggi2(). I'm not advocating this structure. But that is the issue at hand.
A few general tips to help you avoid this in future / or spot it faster:
be consistent with your naming; it's difficult to read your code when you're switching between English and Italian.
it's equally difficult for others to read your code if you don't maintain follow Java conventions with class/method names.
When you're extending Activity, it's typical to append the word "Activity" after your class; in this example new Messaggi2Activity() would have been easier to spot.
Where you're able, pass a Class's dependencies as parameters in the constructor; don't rely on constructing these dependencies yourself inside that class. Once you do this, you can begin to draw lines around what your class is responsible for; the less it's responsible for, the harder it is for your class to mess up.
That problem is for put a variable with no "data", verify your variables
I'm programming an Android application and I got a little problem. I'm trying get a value from the Class A in the Class B but it doesn't return the correct value.
Here's my code to better understand (Sorry for my poor english)!
Class A
package com.androidhive.androidlistview;
//import
public class AndroidListViewActivity extends ListActivity {
int day;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// storing string resources into Array
String[] adobe_products = getResources().getStringArray(R.array.adobe_products);
// Binding Array to ListAdapter
this.setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item, R.id.label, adobe_products));
ListView lv = getListView();
// listening to single list item on click
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// selected item
String product = ((TextView) view).getText().toString();
// Launching new Activity on selecting single List Item
Intent i = new Intent(getApplicationContext(), SingleListItem.class);
day = Integer.parseInt(product.replaceAll("[^\\d.]", ""));
System.out.println(day);
//prints 1 When I click on the first list item, 2 When I click on the second, ...
startActivity(i);
// sending data to new activity
i.putExtra("product", product);
}
});
}
public int getDay() {
return day;
}
}
Class B
package com.androidhive.androidlistview;
//import
#SuppressLint({ "NewApi", "HandlerLeak" })
public class SingleListItem extends Activity {
AndroidListViewActivity alva = new AndroidListViewActivity();
int day;
String url;
String code;
//others variables
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Graphic
new NetworkOperation().execute();
}
class NetworkOperation extends AsyncTask<Void, Void, String> {
protected String doInBackground(Void... params) {
Document doc;
try {
day = alva.getDay();
System.out.println(day);
//prints 0
url = "http://www.planetehockey.com/calendrier.php?saison=45&div=9&club=&journee=" + day + "&jour=&mois=&page=0";
doc = Jsoup.connect(url).get();
//Récupère le texte d'une balise ayant bg_tableau pour class
Elements getId = doc.getElementsByClass("bg_tableau");
code = getId.text();
code = code + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
handler.sendEmptyMessage(1);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
//other code
}
};
}
Thank's a lot for all your answers it helped me a lot:
How I solved the problem:
Class A
i.putExtra("product", product);
startActivity(i);
and:
Class B
int day = Integer.parseInt(i.getStringExtra("product").replaceAll("[^\\d.]", ""));
In your Class A, you're trying to bundle components AFTER the activity has been called.
put the call function like this..
Intent i = new Intent(getApplicationContext(), SingleListItem.class);
day = Integer.parseInt(product.replaceAll("[^\\d.]", ""));
System.out.println(day);
i.putExtra("product", product);
startActivity(i);
The passes the parameter in a bundle to the called activity.
HTH!
There are two simple solutions for your problem,
1. Pass day values in intent to SingleListItem
Or
2. Make day as a Static member and use it with class Name like,
public static int day; and access it `AndroidListViewActivity.day`
and remove public int getDay() method from AndroidListViewActivity as in both activity it refers a different object of AndroidListViewActivity .
Try doing i.putExtra("product", product); before startActivity(i);
In your Activity A you have written the getter method but not setter method to set the value of day in your code. Just write the setter method also and set the value of day.
public void setDay(int p_day)
{
day=p_day;
}
Make the variable day as static. After setting the day value try to get it in activity B.
I hope this will help you.
I don't know why it shows an error. Can somebody help me.
public class MainActivityT extends Activity {
private VerlaufDataSource datasource;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_t);
datasource = new VerlaufDataSource(this);
datasource.open();
List<Entry> values = datasource.getAllEntries();
ArrayAdapter<Entry> adapter = new ArrayAdapter<Entry>(this,
android.R.layout.simple_list_item_1, values);
In the next Line it shows me an error, namely:
Multiple marlcers at this line
- The method setArrayAdapter(ArrayAdapter< Entry>) is undefined for the type MainActivityT
-Uno broakpoint:MainActivityT [lino: 3S] - onCroato(Bundlo)
- The method setlistAdapter(ArrayAdapter< Entrv>) is undefinod for tho type MainActivitvT
setListAdapter(adapter);
}
List<Entry> AufgabenListe = new ArrayList<Entry>();
public void VerlaufKlick(View view)
{
#SuppressWarnings("unchecked")
In the next Line it shows me an error, namely:
Multiple makers at this line
- The method getArrayAdapter() is undefined for the type MainActivityT
- The method qetlistAdapter() is undefined for the tvpe MainActivitvT
ArrayAdapter<Entry> adapter = (ArrayAdapter<Entry>) getListAdapter();
Entry comment = null;
switch (view.getId())
{
case R.id.button1:
String[] comments = new String[] { "Cool", "Very nice", "Hate it" };
int nextInt = new Random().nextInt(3);
comment = datasource.createEntry(comments[nextInt]);
adapter.add(comment);
break;
}
adapter.notifyDataSetChanged();
}
#Override
protected void onResume()
{
datasource.open();
super.onResume();
}
#Override
protected void onPause()
{
datasource.close();
super.onPause();
}
}
Your activity need to extend ListActivity instead of Activity.
There is no method setListAdapter/getListAdapter available in Activity class. They are available if you extend ListActivity.
Read this post on how to use ListActivity.
Use ListActivity instead of Activity as base class