Java in Android, Problems in array - java

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)};

Related

How to run a class multiple times?

I want to run a class multiple times, lets say I have a class
public class setTextClass {
public void setTextClass (String text){
this.text = text;
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
textview.setText(text);
}
public void run{
textview.setText(text);
}
}
So, As I see, if I initiate the class doing:
setTextClass hi = new setTextClass("hello");
The code on the onCreate will run right? (this is my first question)
And then, if I run the code:
hi.run()
The code over the run method will be executed and also will pass the text variable that was assigned at the initialization?. This is my second question. I'm learning java, sorry if this is a really basic question
First of all, it's difficult to address question with basic java and Android misconceptions in a Stack Overflow answer. SO is not made for these kind of question, that's why you are getting downvotes. So, that said, I'll try to help you a little bit:
First answer: "The code on the onCreate will run right? (this is my first question)"
No. You are probably mixing up because of onCreate method from Android's Activity class, right? But a constructor is something general for all classes in java, while onCreate is a method specific to some Android complex classes, like Activity or Fragment. It is a method related to the lifecycle of these classes and you should read more about it here.
So, in this simple class that you showed, onCreate will not be called in the constructor (unless you explicitly call it in the constructor). You should assign the text to textView inside your constructor.
Second question: "The code over the run method will be executed and also will pass the text variable that was assigned at the initialization?"
Yes, it will run and use the variable assigned to this.text on the constructor. BUT, you are missing the declaration of this global variable for it to work:
public class setTextClass {
private TextView textView;
private String text; // You have to declare your global variables here
public void setTextClass (TextView textView, String text){ // You should pass your TextView in the constructor and assign it to your global variable, so it's not null when you assign text to it;
this.textView = textView;
this.text = text;
textview.setText(text); // Moved from your onCreate method to the constructor
}
public void run{
textview.setText(text);
}
}
I hope I could make myself clear, but you should study more java and do some basic tutorials to better understand the language and it's concepts, so you can ask more specific questions here. Read here about classes, objects, constructors and more
Your onCreate function will not run when you do the initialization:
setTextClass hi = new setTextClass("hello");
instead what will run as its constructor(which should not have a return type because its return type is the object itself) ie:
public setTextClass (String text){
this.text = text;
}
And as for the second question the text variable, that variable only exist in the scope of the constructor or setTextClass method. So if you wanted to do something like that you would need to create and set a class variable.
It seems like you need to do a lot more learning and go through examples of OOP design and scope. I would check out these resources if i were you:
http://www.learnjavaonline.org/en/Objects
http://www.learnjavaonline.org/en/Functions

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.

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.

Access in a static way or via parameter?

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.

How can I pass a reference to the current activity

I am trying to pass a reference of the current activity to an object but can't seem to find a method that will do this easily. Previously I was able to do this simple passing with the "this" reference of the current context. I then changed my activity from implementing OnClickListener to creating an OnClickListener object so that I could pass it as a parameter. This is when I ran into trouble as I was trying to create the object after I clicked on a button, this means I can no longer pass the activity with "this" because "this" is now a reference of the OnClickListener.
public class MyActivity extends Activity {
private Object mObject;
private OnClickListener mListener = new OnClickListener() {
public void onClick(View v) {
Object mObject = new Object(this);
}
}
}
public class Object {
private Activity mActivity;
public Object(Activity a) {
mActivity = a;
mActivity.setContentView(R.layout.layout);
}
}
Seems like an easy fix but I can't find the answer...
Any help is greatly appreciated.
You are right, this now references the OnClickListener, as it references the current class, and you are working inside an anonymous class. You can reference the outer activity by passing mActivity.this:
Object mObject = new Object(mActivity.this);
Btw: I think I'd rename the mActivity class, as normal class naming convention is for it to start with an uppercase letter.
Add mActivity. to this
Object mObject = new Object(mActivity.this);
In your context, this refers to a listener instance, but you need the outer class's instance there, so you need to add class name to this

Categories