Search code examples
androidjsonstatic-variables

public static variable has the value , but when i try to show it to textview(in another class) it has no value


my activity flow , Login page->mainpage(in this i have a button to go to Userprofile which has a onclick method)-> button onclick method is "startactivity(Userprofile)" I have a onClick method which loads the activity Userprofile. I want to load the details of the user, i have some static variables but no luck.

public class Userprofile extends AppCompatActivity {
    TextView textView , textView1 , textView2 ;
    Context context_userprofile;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_userprofile);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        func_userprofile_show();
    }

    public void func_userprofile_show(){
        String type = "linkuser";
        DatabaseLink databaseLink = new DatabaseLink(this);
        databaseLink.execute(type);
        context_userprofile = getApplicationContext();
        textView = (TextView)findViewById(R.id.tvprofilepage_user);
        assert textView != null;
        textView.setText(DatabaseLink.thename);
        textView1 = (TextView)findViewById(R.id.tvprofilepage_ign);
        assert textView1 != null;
        textView1.setText(DatabaseLink.theign);
        textView2 = (TextView)findViewById(R.id.tvprofilepage_emailid);
        assert textView2 != null;
        textView2.setText(DatabaseLink.theemail);
    }
}

Now this is a method from diffrent class which extends AsyncTask and "theign" is showing in AlertDialog but not in TextView.

public void decodejson() {
    try {
        JSONObject jsonObj = new JSONObject(myJSON);
        details_json = jsonObj.getJSONArray(TAG_RESULTS);

        for (int i = 0; i < details_json.length(); i++) {
            JSONObject c = details_json.getJSONObject(i);
            thename = c.getString(TAG_NAME);
            theign= c.getString(TAG_IGN);
            theemail = c.getString(TAG_EMAIL);
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }
}

@Override
protected void onPreExecute() {
    alertDialog = new AlertDialog.Builder(context).create();
    alertDialog.setTitle("User Profile Loading...");
}

@Override
protected void onPostExecute(String result) {
    myJSON = result;
    decodejson();
    alertDialog.setMessage(theign);
    alertDialog.show();
}

Solution

  • The problem is that textView.setText is called before AsyncTask has finished.

    To solve the problem you can implement an interface for call the function inside the activity when the info is ready. Assuming the AsynkTask is inside your DatabaseLink class, I will sow you some pseudocode..

    Interface:

    public interface DatabaseLinkInterface {
        public void databaseLinkFinished();
    }
    

    The context will be also the listener. You have the context in your DatabaseLink class:

    @Override
    protected void onPostExecute(String result) {
        myJSON = result;
        decodejson();
        alertDialog.setMessage(theign);
        alertDialog.show();
        DatabaseLinkInterface mListener = (DatabaseLinkInterface) context;
        mListener.databaseLinkFinished();
    }
    

    Implement the interface in your activity and create DatabaseLink in onCreate:

    public class Userprofile extends AppCompatActivity implements DatabaseLinkInterface {
        TextView textView , textView1 , textView2 ;
        Context context_userprofile;
        DatabaseLink databaseLink;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_userprofile);
            Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
            setSupportActionBar(toolbar);
            String type = "linkuser";
            databaseLink = new DatabaseLink(this);
            databaseLink.execute(type);
        }
    
        ...
    

    And finally, in your activity, implements the interface method to know when the data is fetched. Remove func_userprofile_show(). Avoid to use static variables for this purpose.

    @Override 
    public void databaseLinkFinished(){
        context_userprofile = getApplicationContext();
        textView = (TextView)findViewById(R.id.tvprofilepage_user);
        assert textView != null;
        textView.setText(databaseLink.thename);
        textView1 = (TextView)findViewById(R.id.tvprofilepage_ign);
        assert textView1 != null;
        textView1.setText(databaseLink.theign);
        textView2 = (TextView)findViewById(R.id.tvprofilepage_emailid);
        assert textView2 != null;
        textView2.setText(databaseLink.theemail);
    }
    

    I also recommend you to use getters and setters instead of access directly to the attribute (databaseLink.theemail -> databaseLink.getTheEmail())