Which is a better way to code getActivity() , getApplicationContext()? - java

i'm not asking diffrence, but how to use these referenes?, Class level object to store their reference or use getter everytime which is provided by super class, Which is a better code practice: 1. call getActivity(), getApplicationContext() ..etc everytime in a local method or pass method as parameter when required in an activity or fragment.
Store their reference in a class level object and use it whereever it's required with null check in an activity or fragment.
I would like to know what is more efficient and why?
type1:
Class A extends Activity
{
#Override
public void onCreate()
{
methodA(getApplicationContext());
//or if fragment
methodA(getActivity());
Toast.makeText(getApplicationContext(),...).show();
}
private void methodA(Context mContext)
{
......
......
}
private void methodA()
{
Activity activity = getActivity();
......
......
}
}
type2:
class A extends Activity{
private Activity mContext;
private Activity mActRef; //if fragment
#Override
public void onCreate()
{
mContext = getApplicationContext();
mActRef = getActivity();//if fragment;
methodA(mContext);
//or if fragment
methodA(mActRef);
..........
.........
.........
Toast.makeText(mContext,...).show();
}
private void methodA(Context mContext)
{
......
......
}
private void methodA()
{
Toast.makeText(mContext,....).show();
}
}
}

getActivity() and getApplicationContext() both return the context and available throughout the class extend with Activity.
According to my opinion No need to create a global variable for them because they are available at class level. Both are correct but storing the context is not efficient.

Related

how to send data from one activity to another activity in android

I have created an volley list in this i have problem to get data from adapter to activity and this activity to another activity. I have received error cannot cast activity.java to anotherActivity.java below is my code. Please help me anyone thanks.
My Interface itemclick in Adapter class
private OnItemClickGetPlaylist mListener;
public interface OnItemClickGetPlaylist{
public void OnPlaylistItemClick(String playlistName,int numOfItems,String imageViewForPlaylist);
}
public void setOnClickListenerOnPlaylist(OnItemClickGetPlaylist listener)
{
mListener = listener;
}
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String id = playlist.getId_playlist_identify();
String PlaylistName = playlist.getTitile_of_playlist();
String imageOfPlaylist = playlist.getImage_of_playlist();
int numOfPlaylistSongs = getItemCount();
SendIdToDatabase(id);
if (mListener != null)
{
mListener.OnPlaylistItemClick(PlaylistName,numOfPlaylistSongs,imageOfPlaylist);
}
else {
Toast.makeText(context, "mListeren is null" + mListener, Toast.LENGTH_SHORT).show();
}
}
});
After get data handle OnPlaylistItemClick click in Activity below Codes
public void OnItemClickHandleInPlaylistActivity(String playlistName,int numOfItems,String imageViewForPlaylist)
{
//here is the adapter item click in activity now i want to send that data to another activity without any intent please help me.
// i have implement below code but it give me cannot cast activity to another activity error.
((anotherActivity) getApplicationContext()).OnItemClickInMusicActivity(playlistName,numOfItems,imageViewForPlaylist);
}
See the solution at https://stackoverflow.com/a/47637313/2413303
public class MyApplication extends Application {
private static MyApplication INSTANCE;
DataRepository dataRepository; // this is YOUR class
#Override
public void onCreate() {
super.onCreate();
INSTANCE = this;
dataRepository = new DataRepository();
}
public static MyApplication get() {
return INSTANCE;
}
}
The DataRepository should expose LiveData:
public class DataRepository {
private final MutableLiveData<MyData> data = new MutableLiveData<>();
public LiveData<MyData> getMyData() {
return data;
}
public void updateText(String text) {
MyData newData = data.getValue()
.toBuilder() // immutable new copy
.setText(text)
.build();
data.setValue(newData);
}
}
Where the Activity subscribes to this:
public class MyActivity extends AppCompatActivity {
DataRepository dataRepository;
TextView textView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyApplication app = (MyApplication)getApplicationContext();
dataRepository = app.getDataRepository();
setContentView(R.layout.main_activity);
textView = findViewById(R.id.textview);
dataRepository.getMyData().observe(this, new Observer() {
#Override
public void onChange(MyObject myObject) {
textView.setText(myObject.getText());
}
}
}
So to update this text, you need to get the DataRepository class, and call updateText on it:
DataRepository dataRepository = MyApplication.get().dataRepository();
dataRepository.updateText("my new text");
Make sure that the data in DataRepository is properly persisted somewhere, or at least can be obtained again after process death. You might want to use a database for example (but not shared preferences).
If you don't want to use Intents, maybe you can use a publish/subscribe architecture. There is a library called eventbus (org.greenrobot:eventbus) very easy to use which could achieve what you want.
Use an Application Class instead.
public class MyApplicationClass extends Application{
#Override
public void onCreate() {
super.onCreate();
///do something on create
}
getterMethods(){...}
setterMethods(){...}
}
then add android:name=".MyApplicationClass" to manifest file
Now you can access the methods in class by
MyApplicationClass applicationClass = (MyApplicationClass)getApplicationContext();
int id = applicationClass .getterMethod().getID;
String playListName = applicationClass .getterMethod().getPlayListName();
and vice versa for Setter();
after that you can use it for data getting and setting Data throughout the application.
Hope it helps :)
References:
https://guides.codepath.com/android/Understanding-the-Android-Application-Class
I find the best to use callbacks.
in ClassA:
Create interface
MyCallback callback;
viod setCallback(MyCallback callback){
this.callback = callback;
}
viod onStop(){
callback = null;
}
interface MyCallback{
void doSomething(Params params);
}
in ClassB:
implement MyCallback
public class ClassB **implements ClassA.MyCallback**
set reference in onCreate
ClassA classA = new ClassA();
classA.setCallback(this);
// override method doSomething
#override
void doSomething(Params params){
//do your thing with the params…
}
when the job is done inside class A call:
callback.doSomething(params);
destroy reference inside class B in onStop()
classA.onStop();

Setting context on custom listener in a dialog

I created a very simple listener interface that looks like this:
public interface ReportDialogListener {
void shouldRemoveBlockedUser();
}
Now, in my ReportDialog class which is defined like this:
public class ReportDialog extends Dialog implements View.OnClickListener {}
I want to implement this listener and send callback for a certain action. However, when I do send callback after a certain action... my mDialogListener variable is null.
Where do I set the context?
This is what I tried:
private ReportDialogListener mDialogListener;
#Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
try {
mDialogListener = (ReportDialogListener) getContext();
} catch (ClassCastException e) {
}
}
#Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
mDialogListener = null;
}
But when I call mDialogListener.shouldRemoveBlockedUser();, mDialogListener is null...
Also- I made sure my main activity was implementing ReportDialogListener... thanks
Implement Listener in MainActivity
Public class MainActivity implements ReportDialogListener {
ReportDialogListener reportDialogListener ;
public void onCreate(Bundle saveInstanceState){
reportDialogListener =this;
}
#override
public void shouldRemoveBlockedUser(){
}
}
Pass reportDialogListener object to other class or activity and call the listener method reportDialogListener.shouldRemoveBlockedUser();
If this main activity implements the interface, do not use the activity context. Use this instead. mDialogListener = this;
Also i do not see where you implement the interface,only the View onClick interface you have actually implemented.
public class ReportDialog extends Dialog implements View.OnClickListener
to
public class ReportDialog extends Dialog implements View.OnClickListener,ReportDialogListener
To implement the interface in another, either you define it in the constructor of the calling program, or devise a method that does it.
Since my main activity was actually sending this when creating an instance of ReportDialog :
if (mReportDialog == null) {
mReportDialog = new ReportDialog(this);
}
I was able to assign it to a variable in the constructor of ReportDialog
public ReportDialog(Activity activity) {
super(activity);
mActivity = activity;
init();
}
Then, use it like this:
mDialogListener = (ReportDialogListener) mActivity;
Works perfectly.

FindViewById in a non activity class

How can I use findViewById() in a non activity class. Below is my code snippet. I get the error message: "can't resolve method findViewById" if used directly. And if i try to use the class constructor (Where the imageView is available) i get this error "cannot resolve symbol context"
public class MyBroadcastReceiver extends FirstBroadcastReceiver {
Activity activity;
public MyBroadcastReceiver(Context context, Activity activity){
this.context=context; // error here(cannot resolve symbol context)
this.activity=activity;
}
#Override
protected void (Context context) {
// content
}
#Override
public void onButton(Context context, boolean isClick) {
if(isClick) {
ImageView blueImage = (ImageView)activity.findViewById(R.id.imageView);
blueImage.setColorFilter(0xff000000);
}
}
.......
....
// and so on
And below is my MainActivity with MybroadcastReceiver class instance.Is it correct?
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// and so on
}
}
MyBroadcastReceiver myBroadcastReceiver = new MyBroadcastReceiver(MainActivity.this,this);
#Override
public void onActivityResult() {
// some code
}
#Override
public void onInitialized(MyManager manager){
// some code
}
A BroacastReceiver runs entirely in the background, listening for Intents sent either by the OS or other apps. It is not responsible for any UI interactions, and cannot access any views. Therefore, findViewById cannot be used within a BroadcastReceiver.
See also - What is BroadcastReceiver and when we use it?
You have to pass View to the non activity class, before using findViewByid
and
try using
view.findViewByid(R.id.view_id);
Because context is null in Broadcast class. use Broadcast class constructor to pass parent_activity(Where the imageView is available) context in Broadcast to access the context:
public class Broadcast extends BroadCastReceiver {
Activity activity;
public Broadcast(Context context,Activity activity){
this.context=context;
this.activity=activity;
}
.......
....... //so on
and in parent_activity create Broadcast class instance by passing parent_activity context as:
Broadcast broadcast = new Broadcast(parent_activity.this,this);
Use activity instance as:
#Override
public void onButton(Context context, boolean isClick) {
if(isClick) {
ImageView blueImage = (ImageView) activity.findViewById(R.id.imageView); //<--- here
}
}
.........
......... //so on

Pass the context from a fragment inside an activity to another class

I have a fragment which is instantiated by an Activity. The issue that I'm having is that I have another class in the fragment which takes as a parameter an Activity context.
public class LocationQueries {
Activity context;
private static int REQUEST_CODE_RECOVER_PLAY_SERVICES = 200;
public LocationQueries(Activity context) {
this.context = context;
}
public boolean checkGooglePlayServices() {
int checkGooglePlayServices = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(context);
if (checkGooglePlayServices != ConnectionResult.SUCCESS) {
/*
* google play services is missing or update is required
* return code could be
* SUCCESS,
* SERVICE_MISSING, SERVICE_VERSION_UPDATE_REQUIRED,
* SERVICE_DISABLED, SERVICE_INVALID.
*/
GooglePlayServicesUtil.getErrorDialog(checkGooglePlayServices,
context, REQUEST_CODE_RECOVER_PLAY_SERVICES).show();
return false;
}
return true;
}
}
I instantiate that class in my fragment like this
private LocationQueries locationQueries = new LocationQueries(getActivity());
but when I try to use locationQueries.checkGooglePlayServices();
I get Caused by: java.lang.NullPointerException: Attempt to invoke virtual method android.content.pm.PackageManager android.content.Context.getPackageManager() on a null object reference.
It looks like the LocationQueries(getActivity()) doesn't actually pass the activity context. How can I solve this ?
Edit: Everything is working if I do the same from an Activity -> LocationQueries(this);
It seems that you initiate LocationQueries at the wrong place. Indeed, I assume this:
private LocationQueries locationQueries = new LocationQueries(getActivity());
is called as a global variable in your Fragment class.
Instead you should keep your variable as global but set it into onCreate() or onResume(), as follows:
private class Frag extends Fragment {
private LocationQueries locationQueries;
...
#Override
public void onCreate(Bundle inState) {
locationQueries = new LocationQueries(getActivity());
}
}
Your Fragment appears not to be attached to an Activity.
I suspect you have instantiated your LocationQueries object before onAttach(Activity activity) has been called, or after onDetach() has been called on your Fragment.
In such a case, calling getActivity() will return null which is what you then pass to your LocationQueries object resulting in the NPE.

How to get activity context into a non-activity class android?

I have a Activity class from where I am passing some information to a helper class(Non-activity) class. In the helper class I want to use the getSharedPreferences(). But I am unable to use it as it requires the activity context.
here is my code:
class myActivity extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.home);
Info = new Authenticate().execute(ContentString).get();
ItemsStore.SetItems(Info);
}
}
class ItemsStore
{
public void SetItems(Information info)
{
SharedPreferences localSettings = mContext.getSharedPreferences("FileName", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = localSettings.edit();
editor.putString("Url", info.Url);
editor.putString("Email", info.Email);
}
}
ANy idea how this can be achieved?
Instead of creating memory leaks (by holding activity context in a class field) you can try this solution because shared preferences do not need activity context but ... any context :) For long living objects you should use ApplicationContext.
Create the application class:
public class MySuperAppApplication extends Application {
private static Application instance;
#Override
public void onCreate() {
super.onCreate();
instance = this;
}
public static Context getContext() {
return instance.getApplicationContext();
}
}
Register it at manifest
<application
...
android:name=".MySuperAppApplication" >
...
</application>
Then you can do something like this
public void persistItems(Information info) {
Context context = MySuperAppApplication.getContext();
SharedPreferences sharedPreferences = context.getSharedPreferences("urlPersistencePreferences", Context.MODE_PRIVATE);
sharedPreferences.edit()
.putString("Url", info.Url)
.putString("Email", info.Email);
}
Method signature looks better this way because it does not need external context. This can be hide under some interface. You can also use it easily for dependency injection.
HTH
Try this:
class myActivity extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.home);
Info = new Authenticate().execute(ContentString).get();
ItemsStore.SetItems(Info, getApplicationContext());
}
}
class ItemsStore
{
public void SetItems(Information info, Context mContext)
{
SharedPreferences localSettings = mContext.getSharedPreferences("FileName",
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = localSettings.edit();
editor.putString("Url", info.Url);
editor.putString("Email", info.Email);
}
}
You need to pass the context to the constructor of non activity class
ItemsStore itemstore = new ItemStore(myActivity.this);
itemstore.SetItems(Info);
Then
Context mContext;
public ItemsStore (Context context)
{
mContext =context;
}
Now mContext can be used as Activity Context.
Note: 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)
Write a public function in your activity. While creating an instance of your helper class in Activity class, pass the context of activity in constructor.
Then from your helper class, using the activity context, call the public function in activity class.

Categories