Reading parameter field values - android

This is possibly the noobiest of noob questions, but I can't find the answer anywhere - maybe because I have my terminology wrong, maybe because it's not possible.
What I'm trying to do is determine whether a chronometer widget in Android is running, but the more general question is:
How do I read the field values that I can see in the IDE/debugger programatically?
For example, if I set a breakpoint after my chronometer is started, in the variables list (or when evaluating the chronometer), I can see a load of useful stuff all beginning with the letter 'm'. For example, mVisible, mRunning, mStarted, but I can't for the life of me figure out how to access them.
I'd like to know if this is possible in both Java and Kotlin, please. I've attached a screengrab of what I'm talking about :)
Thanks,
Iain

I think I've worked this out. I've declared an extension function:
fun Chronometer.isRunning(): Boolean {
val f = this::class.java.getDeclaredField("mRunning")
f.isAccessible=true // make it readable
return f.get(this) as Boolean
}
I can then read the value of mRunning with myChronometer.isRunning()
Suggestions for improvements are welcome. :)

Related

What do the numbers in Android Studio debugger window mean?

What do the highlighted numbers example, 4580, 4581 etc., mean? They are not PIDs, this was crossed checked with the ps command in adb shell.
This number is the Register number of the register where the Object's reference is stored.
What is register number?
Something completely useless from an app developer point of view! I am sure you know about the Dalvik VM on which android applications run. So, the frames in a Dalvik byte code are made up of registers. And these registers store the object references. Check this link to know more. Not sure why android studio shows them in debugger. I don't see any use of it.
In short: The number may not necessarily be the register number, it could be the ID from ObjectReferenceImpl, which is an implementation of ObjectReference interface from Java Debug Interface (JDI).
In length: From analysis of Idea Community code base, ThreadDescriptorImpl.java (ThreadDescriptorImpl), was found to be the class responsible for providing the thread description to be displayed in the debug window (please refer above image presented with the question). The ID is referred as thread.uniqueID(). The thread here is of ThreadReferenceProxyImpl type which extends ObjectReferenceProxyImpl, where the uniqueID method is implemented. This method in turn returns a uniqueID from an object of ObjectReference type. Upon cursory search the ObjectReference definition with satisfying criteria was not found in Idea code base. It was later found to be hidden in the definition of JDI interface. From the JDI implementation jar found in the Idea setup, ObjectReferenceImpl was found to provide the final implementation of uniqueID method. The code snippet is listed below -
private long myID;
private static synchronized long nextID()
{
return nextID++;
}
ObjectReferenceImpl(VirtualMachine aVm, Oop oRef)
{
super(aVm);
this.saObject = oRef;
this.myID = nextID();
}
public long uniqueID()
{
return this.myID;
}
However in saying so and answering the question, words like 'probably' and 'may be' were used because, the references for ObjectReference implementations were not found immediately in the Idea Community edition source code. And, the inferences were from the jar implementations. If direct references were to be provided in the future by someone looking at this question and answer, the answer can be modified to reflect certainty.

Android Realm copyToRealmOrUpdate updates existing fields

When using copyToRealmOrUpdate it also overrides fields with existing values. I would expect it would only update the fields I gave and use the existing values for the other fields.
I saw this issue for createOrUpdateFromJson: https://github.com/realm/realm-java/issues/933
cmelchior says this:
It is impossible to tell the difference between an value not set and
it's default value, so there it should override all properties.
I wanted to create an issue with label enhancement for realm, but instead I ask it here first. Is it really impossible? Because it would be a great improvement to me.
Thanks!
Note there is difference between using Realm.copyToRealmOrupdate(RealmObject) and Realm.createOrUpdateFromJson(Json)
The answer I gave is true for copyToRealmOrUpdate() eg. you cannot tell the difference between the following in Java:
boolean bool1;
boolean bool2 = false;
It is different for JSON where you can tell if a property is missing altogether. However the current implementation doesn't work that way. We are currently in process of merging a Pull Request that actually has the behaviour you are looking for. You can follow the progress here: https://github.com/realm/realm-java/pull/1022

Set Global Variable or Repetitively Call Function?

My app has some UI elements that are based on some settings from the user and I am not sure how I should go about coding this for best performance and there doesn't seem to be a good way to Google this to try to find if this has been asked previously.
Basically I want to check for the App Version UI set in the settings and I currently do it via a function:
public String appVersion() {
appSettings = currentActivity.getSharedPreferences(APP_SETTINGS, 0);
String prefAppVersion = appSettings.getString("appVersion", "v2");
return prefAppVersion;
}
Then I will display certain UI elements via an if/else statement:
if (appVersion().equals("v2")) {
// do something here
}
else {
// do something else
}
Is this going to cause memory problems if I call the function 5-6 times within my app (getting a SharedPreference over & over again) or am I better somehow declaring a global variable that gets the SharedPreference once and then uses that for the tests? My only concern with that being if the Preference changes and the UI needs to be redrawn if the variable is not reset.
Your thoughts / input is greatly appreciated.
I don't think the appVersion function will cause any memory problem, but maybe make appSettings as a local variable would be a better practice.
I don't understand the second question, do you mean how to know the preference being changed? SharedPreferences.OnSharedPreferenceChangeListener may help you.

Android Spinner - System view VS User view

I have been creating Spinner controls (Combo boxes/Drop downs) in one of my apps, and was surprised to find out how difficult it was to achieve all of the following features:
User facing Strings are externalized, taking advantage of strings.xml internationalisation (I18N) feature of Android.
Spinner selections operate using a System view, which facilitates not having to work with or map Strings to meaningful values (yuck).
User view to System view mapping should be easy, automated and minimal (i.e not hand rolled for every component).
Others have attempted solutions to this, but universally as far as I could see they suffer from one or many of the following problems:
UI code is creeping into their enum class which doesn’t belong there (messy), nearly all existing solutions suffered from this.
Hardcoded User facing Strings in their enum classes. Because these are not externalized you cannot do I18N using the stock Android features.
Authors typically make the Fragment or Activity an OnItemSelectedListener which perpetuates a common problem of inheritance for convenience, where composition is more appropriate.
I have developed my own solution which does this: http://www.androidanalyse.com/android-spinner-externalize-user-strings-mapped-to-system-enum/
My question is, have I missed something? This seems like something that should not have been this hard (which makes me feel like I'm possibly reinventing the wheel).
Below is some example code showing my solution in-use (which is available Apache 2 license from the link above).
String none = getString(R.string.none);
String light = getString(R.string.light);
String medium = getString(R.string.medium);
String strong = getString(R.string.strong);
SpinnerUtil.createNewSpinner(view, R.id.wind, Arrays.asList(none, light, medium, strong), WindLevel.values(),
new SpinnerItemSelectedListener<WindLevel>() {
public void onItemSelected(Spinner item, WindLevel value) {
// Take whatever action you wish to here.
}});
I would just use ArrayAdapter<WindLevel>. Yes, you created a custom typed listener, but the regular event listener gets the position and can call getItem() on the ArrayAdapter<WindLevel> to get a WindLevel properly typed.
IMHO, the vast majority of Spinner widgets will be populated with material read in from a database, the Internet, or some other dynamic data source, rather than populated by some sort of enum with display values coming from static strings that can be internationalized ahead of time.
This is not to say that your code is useless: if you find it useful, then it was worth writing. And I am sure that there are apps out there that contain your targeted pattern (i.e., a Spinner backed by an enum or equivalent where the display values are known in advance and can be internationalized) who might find your solution useful as well. Every developer who writes enough code cooks up these sorts of helper classes and the like that help map an OS or framework model into something that better fits the developer's own mental model. So long as you are not perceiving any performance issues, it's all good.
Also, note that OnItemSelectedListener is an interface; implementing that interface on an existing class is not inheritance.
I believe the reason nobody answered you is :
What problem are you trying to solve ? Spinners existed prior to your well designed attempt.
Why reinvent them in exactly the same way they exist in Android ?
http://developer.android.com/guide/topics/ui/controls/spinner.html
It is a beautiful wheel indeed you designed, but still, it is just a wheel :)
UPDATE :
I think I begin to understand what you did. This is interesting. I'm not sure why you did not go to the pattern implemented by the ListPreference with its entries and entryvalues.
In fact, I'm not sure I understand why the Android team did not go that route either.
In any case, it is worth proposing your idea to the Android framework. It is after all open source.

if statement crashing my Android application

I need help with using an if statement in java, here is my code :
if(ans==1)
{
txtans.setText("This is a Prime Number");
}
else
{
txtans.setText("This is NOT a Prime Number");
}
if I remove the setText methods in both statements my program works, but when I leave them there and the program finds ans, then it quits, I'm wondering whats wrong with the statements? or is it not possible to use the setText method within if statements..if so how do I overcome this? What I want to do is print a string to the TextView layout when the ans = 1, any suggestions?
Yes, you can run txtans.setText() in an if statement just as well as you could run it if it wasn't in an if statement. You likely just don't have txtans initialised properly.
A quick google search brought up this as a way to print text to a textview.
Check your code, this erros usually comes when use findViewById() method in a wrong view.
In the activity you use like this findViewById(), maybe you need to call yourView.findViewById();
(If you post your class we can help you with more detailed answear.)
Also note that it is not allowed to call methods from Views from another Thread which created them. But a LogCat output including the Error will enlight us for shure :)
txtans might be NULL and you are trying to access a member of a NULL object.

Categories

Resources