Access in a static way or via parameter? - java

public class RootActivity extends Activity
{
static LiLa superLayout;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
main();
setContentView(superLayout);
}
private void main()
{
// LiLa is a class which extends LinearLayout
superLayout = new LiLa(this);
//DownloadData is an AsyncTask
DownloadData mDownloadData = new DownloadData(this);
mDownloadData.execute();
}
}
So the AsyncTask change some parts of the superLayout, for now in the AsyncTak, I do :
RootActivity.superLayout.tv.setText("hello");
Would it be better to change :
static LiLa superLayout;
to
LiLa superLayout;
and :
DownloadData mDownloadData = new DownloadData(this);
to
DownloadData mDownloadData = new DownloadData(this, superLayout);
So that it would be possible to do in the AsyncTask :
superLayout.tv.setText("hello");
So question is : is it better to access this kind of parameters (TextView tv for example) or a method to change this TextView through static way or via parameter ?
Thanks for reading me.
EDIT : btw in my code it is a bit more messy it could be more like
RootActivity.superLayout.class1.class2.tv.setText("hello");

It would be better to avoid using a static in this case, and if that means that you need to pass the value as a parameter, that's fine too. (Statics are not O-O, and are generally a bad idea in an O-O design. They also present problems in unit testing.)
It is also generally a good idea to declare all instance variables and provide getter and/or setter methods if that is required.

I don't think static access to a layout is the best way of doing it.
A better solution would be to save the layout as a private variable and then add your AsyncTask as an inner class of your activity:
public class RootActivity extends Activity
{
private LiLa superLayout;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
main();
setContentView(superLayout);
}
private void main()
{
// LiLa is a class which extends LinearLayout
superLayout = new LiLa(this);
//DownloadData is an AsyncTask
new DownloadData().execute();
}
private class DownloadData extends AsyncTask<..., ..., ...> {
//You can reference the variable superLayout here.
//If you need the context, use RootActivity.this
}
}

I think access view in parameter is better way. SO we don't have to make any static reference for the class or activity.

Read the "A public static field/method" part of this link:
http://developer.android.com/resources/faq/framework.html#3
I hope this will help.

Related

unable to access data members of super class in sub class in same activity

I have created an activity named ShowPairedDevices.java in which I have a super class named ShowPairedDevices to show all bluetooth paired devices.
Then I have created another class named Demo in the same activity which extends ShowPairedDevices.
public class ShowPairedDevices extends AppCompatActivity {
ArrayList<String> pairedDevicesList = new ArrayList<>();
public static ArrayAdapter<String> storePairedDevices;
BluetoothAdapter myBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_paired_devices);
ListView myListView = (ListView) findViewById(R.id.listview);
Set<BluetoothDevice> pairedDevices = myBluetoothAdapter.getBondedDevices();
for(BluetoothDevice device : pairedDevices){
pairedDevicesList.add(device.getName());
}
storePairedDevices = new ArrayAdapter< (this,android.R.layout.simple_list_item_1,pairedDevicesList);
myListView.setAdapter(storePairedDevices);
}
}
Then I try to access ArrayList of superclass named pairedDevicesList in subclass , it cannot resolve it.I even tried to create object of superclass in subclass and then call members of super class through its object, but that too doesn't work. Please help.
Here's the subclass code:
class Demo extends ShowPairedDevices{
pairedDevicesList.add("another device name");
}
The "Demo" class makes no sense.
You can't simply access variables like that in the class scope.
Wrap it in a function, or override a current function and access the data like that:
public class Demo extends ShowPairedDevices {
#Override
protected void onCreate(Bundle savedInstanceState) {
pairedDevicesList.add("another device name");
}
}
I guess you are placed your child class in different Package of ShowPairedDevices class.
In that case you MUST use Protected keyword for ArrayList pairedDevicesList. This is called access modifier in Java. Useful link to refer here https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
At some points, you will need this implementation to reuse variables or functions.

move bundle without using intents - android

Is there any way in which I can move a bundle of data from one class to another without actually changing the layout?
For example:
I have 3 classes: class A, B and C.
Now class B has navigation drawer and bottom navigation menu implemented which can be seen on class A and C and also be used at the same time.
However, I have a button in the bottom navigation menu which takes me to class C but the data which I need to view in this is in class A.
Is there any way by which I can just send a bundle of data to class B but without using intents, then retrieve the data from class B and show it on class C?
** EDIT **
P.S : B is an AppCombatActivity extended class and A and C are Fragment extended classes.
Your question is very simple to implement but it can also become a headache. This is what you should do.
class A:
public class A extends Activity {
static A INSTANCE;
String data="A";
#Override
public void onCreate(Bundle savedInstanceState) {
INSTANCE=this;
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public static A getActivityInstance()
{
return INSTANCE;
}
public String getData()
{
return this.data;
}
}
class B:
public class B extends Activity {
String data;
#Override
public void onCreate(Bundle savedInstanceState) {
data=A.getActivityInstance().getData();
}
}
The trick is to create an Instance in class A and then using that instance to access all the public elements like methods, variables etc using that Instance.
Hope this helps :)
I would suggest using a SharedPreferences file to store the data in Class A. Then you can read from the SharedPreferences file wherever you want to show the data.
Refer this page -
https://developer.android.com/training/basics/data-storage/shared-preferences.html
You could use interface for passing data, this the reference
https://stackoverflow.com/a/9977370/2951976

Calling a non-static method from outside the class

I often have to deal with this kind an error when programming in Java on Android.
For example I have a class where I set a flag.
public class ViewActivity extends Activity {
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
...
}
In another class I want to reset the FLAG_KEEP_SCREEN_ON
class DrawOnTop extends View {
...
if (condition) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
but this doesn't work, since I get "The method getWindow is undefined for the type DrawOnTop".
So I try to define a clearFlags method in ViewActivity class
void clearFlags() {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
and to call it from the DrawOnTop class:
if (condition) {
ViewActivity.clearFlags();
}
This doesn't work as well: I get "Cannot make a static reference to the non-static method clearFlags() from the type ViewActivity".
Well, let's make it static then.
static void clearFlags() {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
and then I get "Cannot make a static reference to the non-static method getWindow from the type Activity"
How could I execute such a statement?
If your DrawOnTop class is nested within the ViewActivity you can create a local Context variable and use it to call the getWindow(). If that's not the case then create a receiver in your activity class then from DawOnTop send an intent with your trigger to do whatever the job is. Do not instantiate your activity class, bad idea!
You can send getWindow() as parameter into clearFlags method.
Call clearFlags(Window window) from your activity: WindowHelper.getInstance().clearFlags(getWindow());
Helper class:
public class WindowHelper {
public static final WindowHelper instance = new WindowHelper();
public static WindowHelper getInstance() {
return instance;
}
public void clearFlags(Window window) {
window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
}
I tried to implement the solutions suggested by Aksaçlı and this turned out to be very simple:
In the ViewActivity class DrawonTop is called this way:
mDrawOnTop = new DrawOnTop(this);
The constructor of the second class contains this:
public DrawOnTop(Context context) {
super(context);
Therefore ViewActivity.clearFlags(); has simply to be rewritten as ((ViewActivity)getContext()).clearFlags();
Perhaps you should refer to an initialised object in your static method. So instead of:
void clearFlags() {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
you should create a static instance variable of your window:
private static staticWindowInstance;
void clearFlags() {
getStaticWindowInstance().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
For more information, you should check out the Singleton design pattern.

Java in Android, Problems in array

I'm trying to use the array in my android program.
I did this
public class MainActivity extends Activity {
TextView[ ] answer = { new TextView(this) };
and, I tried to do use answer[0]
but it gives me errors. Is there any problems with me initializing the arrays?
(I want to create, and initialize them at once)
Guys thank you.. figured it out by help!
I did
TextView[] answer;
in Main
and did
TextView[] answer = {new TextView(this)};
in On create
this made me able to use answer in other methods! thank you guyz!
The statement
TextView[] answer = { new TextView(this) };
needs to be in an instance method such as onCreate. If you need to access it outside the method declare it as a class member variable:
public class MainActivity extends Activity {
private TextView[ ] answer;
#Override
public void onCreate(Bundle savedInstanceState) {
...
answer = new TextView[] { new TextView(this) };
}
....
}
It refers to the instance of MainActivity on which onCreate() has been called.
In general, from the Java Language Specification, 15.8.3:
The keyword this may be used only in the body of an instance method, instance initializer or constructor, or in the initializer of an instance variable of a class. If it appears anywhere else, a compile-time error occurs.
When used as a primary expression, the keyword this denotes a value that is a reference to the object for which the instance method was invoked (§15.12), or to the object being constructed. The type of this is the class C within which the keyword this occurs. At run time, the class of the actual object referred to may be the class C or any subclass of C.
You should try this.
public class MainActivity extends Activity
{
TextView[] answers;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
answers = new TextView[]{new TextView(this)};
}
}
It should be defined as:
TextView[] answer = new TextView[]{new TextView(this)};

getResources() from within an enumeration -- Android Studio

I've just started with Android Development. Now, I want to make an enumeration. Each enum-object within that enumeration, I want to assign a name to. I want to get that name from my project resources (res/values/strings.xml).
But from within the enumeration type, I can't call getResources().getString(R.string.string_name).
Is that because the enumeration doesn't extend an activity or something?
How can I fetch the strings from the resources anyway?
Thanks!
P.S. The enumeration is not nested within a class. If it is possible, I want to keep it as a seperate file.
getResources().getString() is simply a shorthand for getActivity().getResources().getString().
So getResources() still rely on having a context (activity, fragment, context, etc).
To overcome this, i personally extended the Application class and made a public static Context available, so you can always access resources and such in your entire application, no matter if you're in an activity or a POJO.
Example:
public class MyApp extends Application {
public static Context context;
#Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
}
}
With this, you can always call:
MyApp.context.getResources().getString(xxxx);
Enumerators are implicitly static. As in when they are created, your activity and therefor its Context is nowhere to be found. If there's no Context, there are no Resources either.
Perhaps what you want to use is a static class with custom constructor instead of an enumerator. Example:
private static class MyConstants {
private Resources mResources;
public String constant1;
public String constant2;
public String constant3;
public MyConstants(Context ctx) {
mResources = ctx.getResources();
constant1 = mResources.getString(R.id.string1);
constant2 = mResources.getString(R.id.string2);
constant3 = mResources.getString(R.id.string3);
}
}
MyConstants mConstants;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_book);
mConstants = new MyConstants(this);
Log.e(TAG, mConstants.constant1);
...
}

Categories