Accessing java variable from native code via JNI giving junk value - java

I'm creating a video player in android. In my android side of the code i have a toggle button for play/pause state. If plafFlag=0, then the video needs to be paused (playFlag is a variable in java part of the code).
In the native side of the code i'm trying to access the value of this playFlag each before each time a frame is displayed onto the screen.
Below is my java part the code:
public class myPlayer extends Activity {
public int playFlag;
.
.
.
.
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.player);
final ToggleButton playFlagBtn=(ToggleButton) findViewById(R.id.toggleButton1);
playFlagBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
if(playFlagBtn.isChecked()){
playFlag=0;
}
else{
playFlag=1;
}
}
});
From this OnCreate function itself i have called the native code where i'm trying to access playFlag variable.
Below is the code snippet using which i'm accessing the playFlag variable:
jclass cls = (*env)->FindClass(env,"com/example/my_decoder/myPlayer"); __android_log_print(ANDROID_LOG_DEBUG,"MYAPP","reference to class obatined",NULL);
jfieldID fidInt=(*env)->GetFieldID(env,cls,"playFlag","I");
__android_log_print(ANDROID_LOG_DEBUG,"MYAPP","fid obtained",NULL);
int Flag=0;
__android_log_print(ANDROID_LOG_DEBUG,"MYAPP","Before fetching flag value",NULL);
playFlag=(*env)->GetIntField(env,jobj,fidInt);
__android_log_print(ANDROID_LOG_DEBUG,"MYAPP","Initial value of playflag=%d",playFlag);
The above native code snippet doesnt give an error. The value is fetched, but it seems like some junk value.
In the logcat i get output like:
03-08 11:21:32.627: D/MYAPP(31220): Initial value of playflag=1085053248
The main intention here is to pause the decoding process if the value of the fetched flag is 0., otherwise continue to decode the frames and render it on the screen. Hence for me it is very important to fetch the right value of the flag from the java part of the code.
Can anyone please explain where i'm going wrong. Or if there is another way to do it.
Waiting for some replies. Thanks in advance.

Related

Java android and json - variable confusion

I have an android app that is retrieving data from a mysql db via php.
It works fine, but i have a (simple) variable problem.
I want to create a variable inside MainActivity class.
Then inside MainActiviy class i have onCreate method - and inside that I have some json stuff that retrieves my data from mysql.
I now want to assign some mysql value to the variable i created in MainActivity class (it is assigned inside onResponse method from the json stuff), and then I simply want to use that variable and write it out on a textview, and I will do that in the bottom of the onCreate method.
But for some reason, it "forgets" the value I assigned to the variable, when I have to use it outside the onResponse method.
(if i set the textview text inside the onResponse method, it works fine).
public class MainActivity extends ActionBarActivity {
// I create the variable here
String someString;
TextView text;
RequestQueue reqq;
String showUrl = "http://www.someurl.com/get_data.php";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.textid);
reqq = Volley.newRequestQueue(getApplicationContext());
JsonObjectRequest jsonob = new JsonObjectRequest(Request.Method.POST,
showUrl, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray dataAr = response.getJSONArray("json_data");
for (int i = 0; i < dataAr.length(); i++) {
JSONObject dat = dataAr.getJSONObject(i);
// Here I want to assign some data from my mysql db to the variable
someString = dat.getString("aar");
// If I set the the textview to display value of someString HERE, it works!
// text.setText(someString);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
System.out.println(error.getMessage());
}
});
reqq.add(jsonob);
// HERE i want to display the value of the variable in the textview!
// - but it doesnt "remember" the value
text.setText(someString);
}
}
If I use static keyword on the someString variable, it remembers the value, but only the SECOND time i open the app!
I'm very new at this, and have tried google, and tried some stuff with a singleton class, but I just don't seem to understand this!
I would love it, if someone could link me some information to help me get this, AND give an example of how my code should be, so it will work!
THANKS! :D
This behavior is due to the fact that
text.setText(someString);
is executed immediately in the onCreate method, & by immediately I mean that it does not wait for any response from the Volley request (the Volley request that you set up before). In other words, you need to wait till you get a response before you set the text on to your TextView.
That's why it successfully sets your TextView's text from within the onResponse method.

Android - losing variables data when partially closing an app

I am using a class with static values called DB (for Data Base) in my application. When I first run the app, a static byte array from this class is filled and used. Then, when I partially close my app (not closing it definitily just put in background) if a reopen it after 20 seconds more or less, the value of the variable is still here but if I let my app in the background for more than 1 minute the value turns to null.
How can I avoid this to happen?
store your variable value to shared preferences and load the value from shared preferences in the onResume() Method of activity and store the value in the onPause() Method.
Handling lifestyle events properly is an important aspect of Android development.
I suggest that you read the following to make sure that you understand what happens to your app when you turn off your screen, change to another application or any other action that might change the state of your app:
http://developer.android.com/training/basics/activity-lifecycle/index.html
My suggestion is to store your data by overriding onSaveInstanceState() like so:
#Override
public void onSaveInstanceState(Bundle savedInstanceState)
{
// Save the user's current game state
savedInstanceState.putInt(STATE_SCORE, mCurrentScore);
savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel);
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
Then on your onCreate(), you can reload it like so:
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState); // Always call the superclass first
// Check whether we're recreating a previously destroyed instance
if (savedInstanceState != null)
{
// Restore value of members from saved state
mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
}
else
{
// Probably initialize members with default values for a new instance
}
...
}
I hope that this helps!
Good luck in your future developing!
I found a solution with the help of the commenters.
For those who had the same problem:
Copy this in all your Activities to ensure that the data is constantly updated in the preferences:
#Override
public void onPause(){
super.onPause();
String bytearray = Base64.encodeToString(DB.bytearray, Base64.DEFAULT);
prefs.edit().putString("BYTEARRAY", bytearray).apply();
}
#Override
public void onResume(){
super.onResume();
String bytearray = prefs.getString("BYTEARRAY", Base64.encodeToString(DB.bytearray, Base64.DEFAULT));
DB.bytearray = Base64.decode(bytearray, Base64.DEFAULT);
}
Then, add this code in all your Activities to ensure that the values are not saved when you close your app.
#Override
public void onDestroy(){
super.onDestroy();
String bytearray = "";
prefs.edit().putString("BYTEARRAY", bytearray).apply();
}

parameter assignment of callback method in android

There are some callback methods in android, like "onCreate" or "onClick".
I have a question about them.
When those callback methods show up in programs,
their parameters are not assigned by programmer.
Should they be assigned first?
For example,
Bundle saveInstanceState = something;
//assign parameter saveInstanceState first. (yet not assigned in real case)
public void onCreate(Bundle saveInstanceState) {
// do something .....
};
or
View v = something;
//assign parameter v first. (yet not assgned in real case)
public void onClick(View v) {
// do something .....
};
All the codes I have read so far don't assign "saveInstanceState"(of onCreate) or
"v"(of onClick) by the programmers.
Does that mean "android will assign those parameters of callback methods itself"?
If so, are all parameters of all callback methods the same case?
For example, "data and camera in onPictureTaken(byte[] data, Camera camera) {};",
are they assigned by android system automatically and programmer doesn't need to assign them?
I can't find relative details in android developer website so far.
If a parameter is assigned by system, not by programmer,
why is there no relative guideline or note about that in android developer website document?
Thanks for reply.
The parameters of a function are assigned by the caller of the function. Example:
int x = 0;
public void test(int x)
{
System.out.println(x);
System.out.println(this.x);
}
test(2);
//prints
//2
//0
So in your case
View v = something;
//assign parameter v first. (yet not assgned in real case)
public void onClick(View v) {
// do something .....
};
v and this.v would reference different objects inside the onClick method body.

code explaination. method within method and some other syntax [duplicate]

This question already has answers here:
How are Anonymous inner classes used in Java?
(18 answers)
Closed 9 years ago.
second day in android self teachin and saw this code bleow.
from what I understood, it seems to me that the code is getting the button value
final Button GetServerData = (Button) findViewById(R.id.GetServerData);
and then I am not sure what happened. Being from php background this syntax looks very unfamiliar that a method is being called as a methods parameter in here
GetServerData.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// WebServer Request URL
String serverURL = "http://androidexample.com/media/webservice/JsonReturn.php";
// Use AsyncTask execute Method To Prevent ANR Problem
new LongOperation().execute(serverURL);
}
});
I also am not sure what View arg0 is.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.rest_ful_webservice);
final Button GetServerData = (Button) findViewById(R.id.GetServerData);
GetServerData.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// WebServer Request URL
String serverURL = "http://androidexample.com/media/webservice/JsonReturn.php";
// Use AsyncTask execute Method To Prevent ANR Problem
new LongOperation().execute(serverURL);
}
});
}
1) This is type casting, the method
findViewById returns something, the method
which called it casts the result to Button.
2) This an anonymous class, this is a class
implementing an interface, the class is defined
right there at the place of its usage.
3) The OnClickListener interface
apparently has one method called
onClick and it has one View argument.
This is what arg0 is. But it does not
seem to be used in the implementing class.
The name arg0 is not really important.
You can name it also x or y or anything else.

Android, Calling view object from code

I am kind of a newbie so excuse me if this question is too simple or too hard.
I have this code in my java file:
public void button_baby_clicked(View v)
{
//do something here
}
this gets called when someone clicks the imagebutton in my xml file, but how do I call this from the java file itself?
Because it's expecting a View object... and I'm guessing I need to recreate that? How?
Edit:
Ok, to clarify, I want to be able to call the above function via a click in my xml file as well as a function under it.
For example:
public void button_baby_clicked(View v)
{
//do something here
}
public void someFunction()
{
x = 10;
button_baby_clicked(); // This should call the above function.
}
In ur ImageButton you have to add an attribute: android:onClick="button_baby_clicked"
In the java file, you have added:
public void button_baby_clicked(View v)
{
//do something here
}
The logic behind this is:
Upon clicking ur imagebutton, this method will automatically get called, i.e "v" argument will be having ur imagebutton.
The advantage of giving like this is: You no need to initialize the imagebutton in ur activity and no need to set click listener too for this imagebutton.
Alright, if you want to have the method invoked every time the view is clicked, do what the others have said.
Alternatively, you can do something like this.
ImageView globalReference;
#Override
public void onCreate(Bundle icicle){
*** CODE ***
globalReference = (ImageView) findViewById(R.id.myImageView);
*** CODE ***
}
Then, whenever you want that to be called with that particular View, simply call
button_baby_clicked(globalReference);
You can also do this with any View object you create dynamically.
View myTv = new TextView(context);
View myLl = new LinearLayout(context);
button_baby_clicked(myTv);
button_baby_clicked(myLl);
Just get a valid View reference within the same scope as the method, and pass it in like any other method. It can even be null if the method is capable of handling it.
Can't you use it like -
mButton.setOnClickListener(new OnClickListener{
#Override
public void onClick(View v) {
button_baby_clicked(v);
}
}
);
??
EDIT :
If you need to call someFunction() from the onClick of a button,and from there,you need to call button_baby_clicked(),you have to get View v object in someFunction. This link might help you. Please refer Start a service on onClick. You can change appropriately.
I believe its best if you refactor your code and put the code in the event handler into a global method that can be called from anywhere. like this:
public void button_baby_clicked(View v)
{
taskToPerform(); // Perform a certain task
}
public void someFunction()
{
x = 10;
taskToPerform(), // Perform the same task again
}
public void taskToPerform()
{
//This is where you write the task you want to perform
}
This way you can reuse the code in the taskToPerform() method anywhere, anytime.

Categories