Get variable value from method to outside - android

private String u_id;
private String u_name;
#Override
public void onSuccess(LoginResult loginResult) {
if(Profile.getCurrentProfile() == null) {
mProfileTracker = new ProfileTracker() {
#Override
public void onCurrentProfileChanged(Profile profile, Profile profile2) {
// profile2 is the new profile
u_id = profile2.getId().toString();
u_name = profile2.getName().toString();
mProfileTracker.stopTracking();
}
};
// no need to call startTracking() on mProfileTracker
// because it is called by its constructor, internally.
}
else {
Profile profile = Profile.getCurrentProfile();
u_id = profile.getId().toString();
u_name = profile.getName().toString();
}
/*new CreateNewProduct().execute();*/
/*updateFacebookButtonUI();*/
}
I want get value u_id and u_name to add arraylist, but it return null. I tried log have result. I need way resolve. Thanks :(
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("u_id", u_id)); // return null
params.add(new BasicNameValuePair("u_name", u_name)); // return null

Yes, adding "" results will not be null, but I want to get the value of the variable inside the onSuccess method to pass to the List below. The list below is in another class in same file with on Success

Variables u_id and u_name can be null only if they were not initialised. You don't set their value when adding the field to the class.
private String u_id; //only type and name set, not the value
I think if you're sure their value have to be set somewhere in the inner methods (doesn't matter in if or else either), it's not so dangerous to leave it like this. Also I would bet you're calling params.add(...)... after the above lines, unless it would cause the variables being null too...
But if you really want to get something back from your variables, you can initialise them as plain empty strings (""),
private String u_id = ""; //the variable's value is set too
and maybe later handle the "empty-string" checking before adding their value to your List<NameValuePair> variable; however it's not necessary. The main thing is: this way you can be 100% sure your variables won't be null...
EDIT #1: I don't know much about the structure of your file which contains onSuccess() method and the class with your list inside of it, but I would say it's another Java class file (MyClass.java or similar). I'm not an expert in Android multithreading, but I would say there is not anything that could block your inner class with your list to access the fields in the outer base class. You can reach fields anytime and anywhere in a class, no matter you want to do it in that very class or in the 10th nested inner class or method.
So unless your code does not look similar to this, I would think my first answer (above the edit) should be the solution. Maybe you should provide the code of your full class(es) to find the best solution, not just parts like you did first time.

Related

Whats make value of variable become empty or back to initialization value in lifecycle

I just curious what makes a value inside of some variable become empty again or back to its initial value in the android life cycle.
First lets take a look at how i create a variable :
public class myData {
public static String myCode = "";
public static String getData(String Choice) {
String theData = "";
if ("Code".equals(Choice) {
theData = myCode;
}
return myCode;
}
public static void setData(String setData,String Choice) {
if ("Code".equals(Choice) {
myData.myCode = setData;
}
}
}
If I want to fill the variable, i usually do this :
myData.setData("value of variable","Code");
And if I want to get the value of the variable, I usually do this :
myData.getData("Code");
I just want to know what makes my variable gone inside of android lifecycle, of course excluding when the application is closed.
I have to try to Log and show the value in onstart , oncreate, onresume and onrestart. And all of them is still have the value inside of my variable intact without any problem.
My client always tells me that my application sometimes gets crash when they open some activity. I also ask if they did something while using my application,
some of them answer that the application get crashed after they got a phone call and when the phone call is ended, the application is started with a crash.
some of them also said that when they open the application and then idle the phone withouth closing the application until the phone become black screen, and when they open it again the application get crashed.
After I check the log, the problem was the variable become empty. which is why I want to know is there another possibilites that makes the value inside of the variable become empty?
As John Lord saying, on low-end device variables might back to its initial value again if there is not enough memory.
So for future reference, I use a shared preference to counter it, here is my structure for fetching the data :
public class myActivity extends AppCompatActivity {
String myCode = "";
protected void onCreate(Bundle savedInstanceState) {
....
SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("myData", Context.MODE_PRIVATE);
myCode = sharedPreferences.getString("Code",null);
....
}
#Override
protected void onResume() {
super.onResume();
SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("myData", Context.MODE_PRIVATE);
myCode = sharedPreferences.getString("Code",null);
}
}
And here is how i set the data :
SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("myData",Context.MODE_PRIVATE);
sharedPreferences.edit().putString("Code","Hello World").apply();
I hope it will be helpful for those who want to search the same thing

Change ObjectBox LiveData Query

I have an ObjectBoxLiveData object with a query that is set at runtime:
private ObjectBoxLiveData<MyObject> myObjectLiveData;
public ObjectBoxLiveData<MyObject> getMyObjectLiveData(Box<MyObject> myObjectBox, String filterTerm)
{
if (myObjectLiveData == null)
myObjectLiveData = new ObjectBoxLiveData<>(myObjectBox.query().equal(MyObject_.filterProperty, filterTerm).build());
return myObjectLiveData;
}
But I also need to be able to change the filterTerm at runtime. My thinking is that I can make a private String currentFilterTerm; object in MyViewModel to see if I need to update the filter term in the LiveData object, but is there a correct way to update the filter term? I worry that setting myObjectLiveData = new ObjectBoxLiveData<> again will leave a memory leak for the previously defined myObjectLiveData or anything tied to it, but I don't see any graceful way to dispose of it or update the query once defined. Is there a way to redefine my query once defined?

Do I stuck in Looper.java?

I have a JsonObjectRequest Get Method (volley), it was working fine, I got an JsonObject and used it for further actions but now it doesn't do what I want..
In the same class like the Get Request, I have the Method processResponse, which creates an "Account" Object and adds it to the Manager List:
private void processResponse(JSONObject response) {
try {
Log.e("processResponse", " called");
final Account user = new Account("","","");
String username = response.getString("Username");
String email = response.getString("Email");
String id = response.getString("Id");
user.setUsername(username);
user.setEmail(email);
user.setId(id);
Manager.AddObjectToUserList(user);
Manager Class with List:
class Manager {
private static List<Account> _ListofUsers = new ArrayList<Account>();
static void AddObjectToUserList(Account acc)
{
_ListofUsers.add(acc);
}
List<Account> getListOfUsers(){
return _ListofUsers;
}
}
I get an JsonObject from the GetResponse, it does successfully process the Response and creates an Object but when i want to return the List in Manager to another class, the "return List" is 0, I don't get the problem, since it was working fine before.
In debug mode, it jumps after the return List into the Looper.java and it doesn't leave this class..
This is happening because of asynchronous behaviour. You are trying to add the object to list after you are creating the list, that's why you are getting 0. If you want to use that list, you need to use it in processResponse method. Please see also this post
Hope it helps.

How to fetch object and array fields with Parse?

I'm unable to properly fetch a ParseObject that contains a field of type 'Object' : after changing manually the 'Object' field value in the Parse DataBrowser and then fetch the ParseObject from the app, the fetched ParseObject still provide the old value for the 'Object' field, but provide the right new value for the 'String' field.
Here is the sample code I use :
public class MainActivity extends ActionBarActivity {
ParseObject object;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
object = ParseObject.createWithoutData("Test", "tvgTg8jAXz");
}
#Override
protected void onResume() {
super.onResume();
object.fetchInBackground().onSuccess(new Continuation<ParseObject, Object>() {
#Override
public Object then(Task<ParseObject> task) throws Exception {
JSONObject data = task.getResult().getJSONObject("data");
String name = task.getResult().getString("name");
Log.d("OBJECT", data.toString());
Log.d("OBJECT", name);
return null;
}
}).continueWith(new Continuation<Object, Object>() {
#Override
public Object then(Task<Object> task) throws Exception {
if (task.getError() != null) {
Log.e("OBJECT", task.getError().getLocalizedMessage());
}
return null;
}
});
}
}
After I change both 'data' and 'name' fields in the DataBrowser, if 'onResume()' is called without a previous call to 'onCreate()' (after locking/unlocking screen for example) then the logs shows the old value for 'data' and the new value for 'name'.
This is a simple code example to highlight the problem I encounter in a bigger project.
Is this a known issue of the Parse Android SDK ? Is there a workaround ?
Thanks
Now that I learned that you have turned on the local datastore I can come with an, at least partial, answer.
Turning on the local datastore has some side effects. One being that only one instance of each object exists locally. So when you call fetchInBackground the second time, object is already populated with data. The problem then (i think) is that the API no longer override 'complex' types (pointers, objects, arrays), perhaps because it could mess up internal relationships in the data store. Since the fact that the data store will recursively save an object (and pointers) so suddenly swapping a pointer might leave objects 'hanging'. (again, only guessing).
Now I must admit that it still confuses me a bit looking at your code, cause it does not seem that you at any point write your object to the data store, however..
What should work is to unpin the object before 'refreshing' it:
object.unpinInBackground.onSuccess(new Continuation<>{
...
// when done call fetch
});
According to Parse, this is a known issue that they will not fix for now : https://developers.facebook.com/bugs/1624269784474093/
We must use the following methods to retrieve JSON objects/arrays fields from a ParseObject :
getMap() instead of getJSONObject()
getList() instead of getJSONArray()
These methods will return Map and List objects respectively.
I found that managing Map and List in my project instead of JSONObjet and JSONArray is not a problem and is even clearer.

JSONObject as class attribute storage/retrieval

In android, I'm using model classes with methods to handle the data manipulation. My data is brought in from webservices as json. I'm contemplating the possibility of using JSONObjects to store the values of class level attributes. But, I don't know of a way to use the JSONObj as the "holder" variable and create access methods. I don't want to predetermine these methods, as jsonRepository should hold the values, not always known at design time
For example, I'd like to have:
public class User {
private JSONObject jsonAttributes;
public User(String json) {
this.jsonAttributes= new JSONObject(json);
}
[IMPLICIT attribute access methods]
public string Prop1() returns jsonAttributes.getString("prop1");
public string Prop1(String newProp1) returns jsonAttributes.putString("prop1",newProp1);
public string Prop2() returns jsonRepository.getString("id");
public string Prop2(String newProp2) returns jsonAttributes.putString("prop2",newProp2);
....
from outside this class then, I would access the attributes simply...
User myUser = new User(someValidJson);
String myString = myUser.Prop1
Misguided? If not, how does one manage implicit property setting/getting?
As was mentioned in the comment above, why not create your user class, with all of the relevant memeber variables, and simply parse your JSON data in order to populate the ionformation in your user class.
There are a lot of ways you can do this, but I would consider using the builder pattern, as it is flexible, which could be useful if your JSON data changes in the future.

Categories

Resources