I am using the TextToSpeech API and I want to seperate some logic into another class.
In the separate class I have put the following method:
public static void sayHello() {
// Select a random hello.
int helloLength = SoundGameScore.Questions.length;
String hello = SoundGameScore.Questions[currentHelloIndex];
currentHelloIndex = (currentHelloIndex + 1) % helloLength;
mTts.speak(hello, TextToSpeech.QUEUE_FLUSH, // Drop all pending entries
// in the playback queue.
null);
I have then created a variable in the main class: static mainclass object;
Within a button in the main class I call the method through this object by using:
object.sayHello();
I am quite new to android, and I know I am doing something wrong as this gives me a process closed error in the emulator. This also shows a nullexception error in logcat. Please help me, thanks.
I think you are getting a NullPointerException because the reference object is null. You would need to initialise the object in order to call an instance method on it.
However since sayHello() is a static method, you do not need to create an instance of the class in order to call the method. Just use mainclass.sayHello().
Your question and code suggests to me that you do not have much experience with Java. Perhaps you should do some tutorials to brush up on your Java coding before jumping into Android development. For example, Java convention is for class names to be capitalised (MainClass) and for references to have meaningful names (i.e. not things like object).
Related
I'm in the process of completely redesigning my Android app. Before, EVERYTHING was in the same class.
So I tried to redraw everything so that the code is clearer apart Admob than the doc advice to put in the Main thread, I separate the different part of my code in class. So I used two technique: I created a songleton that contains variables that I want to have access to constantly,and I call my classes via weak reference.
Here is what it looks like:
For example, the UIManager class that needs to update the game's IU have a weak reference looks like this:
private static SoftReference<UIManager> ManageUI;
static{ManageUI= new SoftReference<>(null);}
static UIManager get()
{
if(ManageUI.get()==null)
{
ManageUI= new SoftReference<>(new UIManager());
}
return ManageUI.get();
}
GameManager Manager=GameManager.getInstance();
to be able to use the findviewbyid for example I place in method argument the main class that is the mainthread
the singleton that contains all my variables that I want to have permanent access to looks like this:
private GameManager()
{}
/** Holder */
private static class Manager
{
/** Instance unique non préinitialisée */
private final static GameManager instance = new GameManager();
}
/** Point d'accès pour l'instance unique du singleton */
public static GameManager getInstance()
{
return Manager.instance;
}
To separate all in different class, I pass argument to my method so I can call au stuff belong to Activity like that:
(My main class is called GamePlay)
void OpenGlobalScene(GamePlay activity)
{
Manager.OnTitle=false;
if (!checkLayout(activity,R.id.globalscene)) {
LayoutInflater(activity,9, true);
LinearLayout GamePlan = (LinearLayout) activity.findViewById(R.id.globalscene);
GamePlan.setAlpha(Manager.AlphaBord);
}
}
For now, I have not noticed any problems except a few slownesses on old android phone 4.4.2.
Also compared to my old code were EVERYTHING was in the same class, it's much easier to change pieces of code (going to the inapp billing V3 was simpler since everything was in one class that I call like the others with weak referencre)
My questions are:
-What are the problems that such a structure might pose?
I had also chosen that structure to not load or leave in memory things that are not useful
-How are chance that Android will erase from memory an action in progress called with weak reference?
-As you can see I pass the activity has argument to the method, sometimes I pass it from a method to another. Is that fact can cause some trouble?
Thank you for your help.
Check Dagger2 is better than the clasic singleton https://developer.android.com/training/dependency-injection/dagger-android?hl=es-419
thanks for your answer and your tips. I'am gonna check this out.
Anyone else know something about consequences on memory when using weak references ?
I am trying to make sense of a class from a library. The class has no constructor, and I think it is being instantiated via reflection. It is a confusing library, and I want to figure out what is creating instances of this class... but I cannot figure out where to put a breakpoint, since there is no constructor.
I have tried the following, and Android Studio 3.4.1 blows right past them:
Line breakpoints on fields in the class that have initializers
Field watchpoints, set for both field access and field modification, for fields that have initializers
A breakpoint on the class declaration (class Foo)
Breakpoints in methods work, and field watchpoints work when the field is accessed later on (but not when it is initialized). So the debugger is working with this class in general.
I cannot readily recompile the library to add a constructor, though I do have source code (not just decompiled bytecode).
Is there another spot that I can put a breakpoint that will show me the stack trace of instantiation of this class?
From the InitelliJ IDEA documentation (on which AS is based):
If you want to set a breakpoint in the default class constructor, set it on the first line of this class, since the default constructor is mapped to it.
https://www.jetbrains.com/help/idea/using-breakpoints.html
Simple test-case to determine breakpoint position:
public class ReflectionTest {
static int test = 1;
public static void main(String[] args) throws Exception {
System.out.println(ReflectionTest.class.getDeclaredConstructor().newInstance());
}
}
Placing the breakpoint on public class ReflectionTest seems to trigger for me.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the meaning of “this” in Java?
I'm still very new to learning Android programming, and I noticed that "this" was used often in parameters for method calls in the language. I'm following The New Boston tutorials through YouTube, but he never really explains quite detailed enough what the 'this' statement means. Can somebody please explain it to me? Maybe dumb it down a bit?
this refers to the instance of the class you are currently coding within.
You cannot use it in a static context because in this situation you are not within any object context. Therefore this doesn't exist.
public class MyClass {
public void myMethod(){
this.otherMethod(); // Here you don't need to use 'this' but it shows the concept
}
private void otherMethod(){
}
public static void myStaticMethod(){
// here you cant use 'this' as static methods don't have an instance of a class to refer to
}
}
In android class.this is used to pass context around.
Formal definition of context: It allows access to application-specific resources and classes, as well as up-calls for application-level operations such as launching activities.
That means if you need to access resources (including R and user interface) you will have to use context.
In java this means the instance of the class that you are in. For example MainActivity.this points to the current instance of the MainActivity. So by using MainActivity.this.foo you are accessing the foo field of MainActivity class.
public class YourClass {
private int YourInt;
public setTheInt(int YourInt) {
this.YourInt = YourInt;
}
}
"this" is used to see whether an attribute or function belongs to the class we're working on, clearer.
Also, you see that setTheInt operation gets an integer named as the same as your attribute. In that function's namespace, YourInt is not this class's YourInt, but a reflection of the integer coming from setTheInt's calls. "this" helps here to divide the outer and the inner "YourInt"s.
i'm developing an app that, when i press a button, downloads a XML file, put the xml data in a custom object and passes it to a second activity.
The problem is that something is wrong: when a call the startActivity() function the app crashes with a Runtime error.
My code is:
public void onClickBtn1(View view)
{
final ProgressDialog dlg = ProgressDialog.show( this, "Data wait", "Waiting data from the site ..");
// Thread to wait data
Thread th = new Thread() {
public void run() {
// Download and parse xml data
final DatiSport dati = new DatiSport();
boolean ret = dati.download();
dlg.dismiss();
// check result
if (ret==true)
{
// -- Ok
handlerUI.post( new Runnable() {
public void run() {
Intent intSec = new Intent(AICSActivity.this, SportActivity.class);
intSec.putExtra("datiSport", dati);
startActivity(intSec);
}
});
}
else
{
The app crashes on the startActivity() call. When i break on the startActivity() line i'm not able to look the variable called 'dati' and i guess this is not well defined.
If i substitute dati with 12345, there is not problem.
Which is the problem with dati ?
--- Changed here cause I'm not enabled to reply myself ---
Ok guys. Thanks for replies!
My guess is that i need to re-design the app data.
My first attempt was: download the XML text and accommodate the data into a (rather) complex object. This object contain a list of championships, each of them contains a list of categories, each of them contains a list of teams.
The problem is that, since the Serializable is not working, the implementation of Parcelable is too complex and it should generate almost the same data as the xml file.
I'm wondering if it should be easier passing directly the xml text to other activities (they have to show in turn the list of championships, then the categories of a selected championship, then the list of teams for a selected category...)
Any other idea?
Extract from this Answer :
Serializable is a standard Java interface. You simply mark a class Serializable by implenting the interface, and Java will automatically serialize it in certain situations.
Parcelable is an Android specific interface where you implement the serialization yourself. It was created to be far more efficient that Serializable, and to get around some problems with the default Java serialization scheme.
Extract from this answer :
Seeing Parcelable might have triggered the question, why is Android
not using the built-in Java serialization mechanism? It turns out that
the Android team came to the conclusion that the serialization in Java
is far too slow to satisfy Android’s interprocess-communication
requirements. So the team built the Parcelable solution. The
Parcelable approach requires that you explicitly serialize the members
of your class, but in the end, you get a much faster serialization of
your objects.
After seeing some answer on StackOverFlow, i come to conclusion that Parcelable is optimized than Serialization in android.
How to make class to Parcelable ?? (Check out this, this & this tutorials)
Use a Serializable or Parcelable when passing objects
You need a class to implement the Serializable class
//to pass :
intent.putExtra("MyClass", obj);
// to retrieve object in second Activity
getIntent().getSerializableExtra("MyClass");
Your class would look something like this;
import java.io.Serializable;
#SuppressWarnings("serial") //with this annotation we are going to hide compiler warning
public class MyClass implements Serializable {
public Deneme(Object obj){
this.obj= obj;
}
private Object obj;
}
The Intent class has a method as
putExtra(String name, int value)
thats why it works when you put 12345 at the place of "value", but there is no overloaded version of putExtra that takes "DatiSport" object.
You must ensure that "DatiSport" is Serializable or Parcelable.
See below for more info-
http://developer.android.com/reference/android/content/Intent.html#putExtra%28java.lang.String,%20java.io.Serializable%29
How to send an object from one Android Activity to another using Intents?
How to pass an object from one activity to another on Android
Make your class implement Serializable interface and then pass object instances in intent extra.
To pass data from one Activity to another :
intent.putExtra("ClassName", obj);
To retrieve data in the Second Activity from the First Activity :
getIntent().getSerializableExtra("ClassName");
I found the problem !!!
An internal class were not implementing Serializable!
In the dump window i saw the internal object 'ioe' that said that there was a NotSerializable error and the name of the class!!
Now i checked each internal class and the data is passed to the next activity.
Thanks a lot
Is something wrong with this construct in Android?
class A extends Activity {
private Object myObject = new Object();
#Override
protected void onCreate(Bundle savedInstanceState) {
//myObject = new Object();
}
}
Because at some point(s) later I get (sometimes, not reproducible yet) exceptions because myObject is null. I don't know if it's because I have to initialize in onCreate.
Edit: Additional details:
The actual class of myObject is List<Object> (Where Object is a domain specific type)
At some point later in the activity I'm storing myObject as a static field of a "Parameter passer" class and starting other Activity (because I'm avoiding to implement Parcelable. If this is good or bad practice should not be discussed here, unless that's causing my error). In the other Activity I pick up myObject. There it's (sometimes) null.
Edit 2: I don't understand why this object becomes null if I'm storing a reference to it as static field of my parameter passer class (a standalone, dedicated class). That's how garbage collection works, right, it just removes when the objects are not referenced anymore. So since I have a static reference this object should not be removed. According to this thoughts, if they are correct, the problem should be somewhere else.
When you start a new activity your old one goes on the block for possible garbage collection (including any classes instantiated in it, including your parameter passer class), so your object is not necessarily going to be available (which is why you see an intermittent failure.).
I see two option:
1) Pass it along in the bundle with your intent that starts the new activity. As you were trying to avoid this, probably not your best choice.
2) Extend the Application class and store the object in there.
EDIT
I think the accepted answer to this SO Question might fix your issue (and explain what is actually happening).
No. That code is just fine. You can create objects in the constructor.
You may want to check a previous question about it Instance variable initialization in java and the section 3.2.4. Field Defaults and Initializers which basically states that the first case:
private Object myObject = new Object();
is identical to an initialization in the class constructor. (NOTICE onCreate is NOT the constructor).
So, myObject should never be null, except in the case the "new Object()" instruction failed, generating an exception.
Isn't this possible your code is changing the contents of myObject later on the code?