Why does the following method throws an NPE,
public ActivityOne extends Activity{
DataManager dtMan = new DataManager(this)
public onCreate (){
...some source code here...
dtMan.check();
}
}
public class DataManager(){
private Context myContext;
public DataManager (Context context){
myContext = context;
}
Helper helper = new Helper(this);
public boolean check(){
helper.open();
...some source code here...
}
}
When I view the logcat; I get a java.null.pointer exception, so I did something like
public class DataManager(){
private Context myContext;
public DataManager (Context context){
myContext = context;
}
public boolean check(Context context){
**Helper helper = new Helper(context);**
helper.open();
...some source code here...
}
}
And it worked, so what is the difference between the two DataManager in Java/Android programming perspective, thus this approach if I understand correctly must be replicated to as follow:
public class DataManager(){
private Context myContext;
public DataManager (Context context){
myContext = context;
}
public boolean check(Context context){
**Helper helper = new Helper(context);**
helper.open();
...some source code here...
}
public boolean check2(Context context){
**Helper helper = new Helper(context);**
helper.open();
...some source code here...
}
public boolean check3(Context context){
**Helper helper = new Helper(context);**
helper.open();
...some source code here...
}
}
Meaning I just can't declare the Helper Class once and use it anywhere the calling class, did I forgot some fundamentals? Please clarify.
Will the context also lead to memory leaks?, if so, how will I fix it?
#EDIT:
Well I forgot to include the Helper Class
public class Helper{
private Context myContext;
public Helper(Context context){
myContext = context;
}
public void open(){
//do stuff here
}
}
Your code does not work because the DataManager is initialized at field scope in the Activity.
Classes which need a Context should always be initialized in one of the Activity's life cycle methods:
onCreate, onStart, onDestroy, etc.
Like this:
private DataManager dataManager;
public void on create(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
dataManager = new DataManager(this):
}
You also should initialize the Helper class in the DataManager constructor:
public class DataManager(){
private Context context;
private Helper helper;
public DataManager (Context context){
this.context = context;
this.helper = new Helper(this.context);
}
public boolean check(Context context){
helper.open();
//...some source code here...
}
}
To prevent memory leaks you just need to make sure the DataManager class is not a static instance with an Activity Context.
If you don't need an Activity Context but you're also fine with an Application Context you should use it:
public DataManager(Context context){
this.context = context.getApplicationContext();
//...
}
Try put
dtMan = new DataManager(this)
in onCreate method in Activity?
Related
To get context, I use:
Context context = InstrumentationRegistry.getInstrumentation().getContext();
But I didn't found any method like getApplicationContext();
Any leads would be appreciated
Try this way:
Your_Activity.this
Or you can create a public static method to get the Context:
public class App extends Application {
private static Application sApplication;
public static Application getApplication() {
return sApplication;
}
public static Context getContext() {
return getApplication().getApplicationContext();
}
#Override
public void onCreate() {
super.onCreate();
sApplication = this;
}
}
Or get it through a View, using Your_View.getContext()
Hope this help
I want to access a class extending SQLiteOpenHelper to get the context of database from a java class. I need to pass application context to get that but don`t have access to getApplicationContext().
How can I get Application Context in java class that is not activity?
I suggest you create a constructor that has a parameter of the Context type.
public class MySQLiteOpenHelper extends SQLiteOpenHelper {
// Variables
private Context ctx;
public MySQLiteOpenHelper(Context ctx) {
this.ctx = ctx;
}
//More code
}
Now, in your activities, you can do this:
MySQLiteOpenHelper helper = new MySQLiteOpenHelper(this);
And in your fragments, you can do this:
MySQLiteOpenHelper helper = new MySQLiteOpenHelper(getActivity().getApplicationContext()); //getActivity() would work too, Activity (indirectly) extends Context.
You can create custom Application class and write method getContext().
Someting like this:
public class MyApplication extends Application {
private static MyApplication mCurrentInstance;
#Override
public void onCreate() {
super.onCreate();
mCurrentInstance = this;
}
public static MyApplication instance() {
return mCurrentInstance;
}
public static Context context() {
return mCurrentInstance.getApplicationContext();
}
}
And add this class into manifest:
<application
android:name=".MyApplication">
I'm playing with the GCM.
Everything is perfect using the example on https://code.google.com/p/gcm/source/checkout
Im getting notifications on my app with the gcm messages,
Now I want to add the message in a listView located on my MainActivity.
Im receiving my messages on a different class (GcmIntentService.java). How can I get MainActivity context to sendBroadcast.
Already tried with
private static Context mContext;
public static Context getContext() {
return mContext;
}
public static void setContext(Context context) {
mContext = context;
}
But is not working.
Any Ideas.
Thanks
I am not sure what you are doing. But keeping the below in mind
Do not keep long-lived references to a context-activity (a reference to an activity should have the same life cycle as the activity itself).
http://www.curious-creature.org/2008/12/18/avoid-memory-leaks-on-android/
You can do as below
Example:
new MyClass(ActivityName.this);
class MyClass
{
Context mContext;
public MyClass(Context context)
{
mContext=context;
}
}
pass the context variable through constructor .
create new activity like below
public class GetContext extends AppCompatActivity {
Context mainActivity;
public GetContext(Context mainActivity){
this.mainActivity = mainActivity;
}
and in your previous mainActivity send this context as below
GetContext sendContext = new GetContext(mainActivityContext);
where mainActivityContext is Context mainActivityContext = this;
or simply pass this instead of mainActivityContext
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_get_attendance_from_database);
}
i have a problem NullPointerException on getWritableDatabase()
public class DatabaseTable extends Activity {
private Context context;
#Override
public void onCreate(Bundle savedInstanceState) {
LBD conection = LBD.get(this);
super.onCreate(savedInstanceState);
}
}
There is an implementation does not work "openHelper.getWritableDatabase()"
public class LBD {
private Context context;
private static SQLiteDatabase db;
private OpenHelper openHelper;
public static LBD get(Context context) {
LBD lbd = new LBD(context);
lbd.open();
return lbd;
}
public LBD(Context c) {
context = c;
}
final public void open() {
openHelper = new OpenHelper(context);
db = openHelper.getWritableDatabase();
}
public class OpenHelper extends SQLiteOpenHelper {
OpenHelper(Context context) {
super(context, "rss_base.db", null, 3);
}
}
}
I realized, I forgot to initialize the onCreate Thanks to everyone
Most likely your Context
openHelper = new OpenHelper(context);
is null. Make sure that your Context is set. But i recommend to you provide more details, add here your logcat.
Problem is not in your Database Class, its at DatabaseTable.onCreate()..... java:27
Please check it out.
Thanks,
Haps.
MyI don't understand why I get a compile error for this:
public class Main_screen extends ListActivity {
List<Object> completeList;
private My_ArrayAdapter adapter;
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
completeList = getCompleteList();
adapter = new My_ArrayAdapter(this, completeList);
setListAdapter(adapter);
}
public void doSth() {
...
}
}
and in My_ArryAdapter:
public class My_ArrayAdapter extends ArrayAdapter<Object> {
private final List<Object> list;
private final Activity context;
public My_ArrayAdapter(Activity context, List<Object> list) {
this.context = context;
this.list = list;
}
public void tryIt() {
context.doSth(); // <-------- THIS DOES NOT WORK, this method can not be called
}
}
Please explain, is there something fundamental I have not understood. I am just passing the context into the ArrayAdapter instance I create. And from within this instance I would like to acccess the caller's method.
Why shoudl this not be possible?
Many thanks!
try this:
public void tryIt() {
((Main_screen)context).doSth();
}
context is Activity and it hasn't doSth(), but Main_screen has, so you should cast to this class
Actually you are making Activity context object and passing a child of Activity (i.e Main_Screen), Its called upward cast (Implicit Casting).
So the Activity (as parent) has no method of doSth(). So you need downward Casting (Explicit casting) to make it a Main_Screen.
Two ways to do this.
make an Object of Main_Screen context instead of Activity context
or
cast it as Main_Screen in tryIt() method to avail Main_Screen methods like this way:
if(context.isInstance(Main_Screen.class))
{
((Main_Screen)context).doSth()
}
you can also use try catch to minimize the chances of ClassCastException
You can use the below code. Obviously class context don't contain an object doSth(). doSth() is declared in class Main_screen.
public class My_ArrayAdapter extends ArrayAdapter<Object> {
private final List<Object> list;
private final Activity context;
public My_ArrayAdapter(Activity context, List<Object> list) {
this.context = context;
this.list = list;
}
public void tryIt() {
Main_screen.doSth();
}
}
How I did it
StaticCommonDataClass -> maintains static data here I will keep the instance of Activity one in it.
ActivityOneClass -> Contains the method that I have to access in ActivityTwo actually.
ActivityTwoClass => Will access the ActivityOne Method.
What I hate is to pass two many parameters from one function to other function or one class to other class,
that too when it has to be done for similar values again and again.
Here i will store refrence of ActivityOneClass in static Variable.
public class CommonStaticData {
private static Activity _activity;
private static Context _context;
public static void setactivity(Activity activity) {
_activity = activity;
}
public static Activity getactivity() {
return _activity;
}
public static void setcontext(Context context) {
_context = context;
}
public static Context getcontext() {
return _context;
}
}
public class ActivityOneClass extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity1);
CommonStaticData.setactivity(ActivityOneClass.this); //will keep the instance alive for this activity
}
Public void activityOneMethod()
{
//Set of statements
}
}
public class ActivityTwoClass extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity2);
((ActivityOneClass) CommonStaticData.getactivity()).activityOneMethod();
//we need to typecast the instance stored in CommonStaticData.getactivity() to "ActivityOneClass" thats is the
//activity containing the method so as to access the method otherwise it will not come in the intellisense window and will generate Compiler Error
}
}