将JSON数据传递给主要活动

时间:2016-06-16 13:34:37

标签: android json

我正在尝试使用JSON和PHP将我的应用程序连接到Mysql数据库。 PHP脚本返回一个JSON数组,用于确定灯的状态(true或false)。

我尝试将JSON代码放在单独的类中,该代码打开URL连接并获取状态。因此,每当我需要使用它时,我都可以调用它。

问题是变量res在JSON类中确实有一个值,但是当我尝试使用JSON对象从主Activity访问它时,它是空的。任何人都可以指导我找到解决这个问题的正确解决方案吗?

主要活动

public class MainActivity extends AppCompatActivity {
public TextView t;
@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  t = (TextView) findViewById(R.id.t1);
  Json j = new Json();
  j.execute("http://127.0.0.1/web/test.php");
  t.setText(j.res);
 }
}

Json class

public class Json extends AsyncTask<String, String, String> {
String result = "";

public String res="";

@Override
protected void onPreExecute() {
}
@Override
protected String doInBackground(String... params) {
    InputStream isr = null;
    try {
        String URL = params[0];
        java.net.URL url = new URL(URL);
        URLConnection urlConnection = url.openConnection();
        isr = new BufferedInputStream(urlConnection.getInputStream());
    } catch (Exception e) {
        Log.e("log_tag", "error in http conection" + e.toString());
    }

    try {
        BufferedReader reader = new BufferedReader(new InputStreamReader(isr, "iso-8859-1"), 8);
        StringBuilder sb = new StringBuilder();
        String line = null;
        while ((line = reader.readLine()) != null) {
            sb.append(line + "\n");

        }
        isr.close();
        result = sb.toString();
    } catch (Exception e) {
        Log.e("Log", "failed " + e.toString());
    }
    return null;
}

JSONObject json;
protected void onPostExecute(String result2) {

    try {

        String password1 = "";
        JSONArray jArray = new JSONArray(result);
        for (int i = 0; i < jArray.length(); i++) {
            json = jArray.getJSONObject(i);
            res=json.getString("status");

            break;
        }
    } catch (Exception e) {

    }
  }
}

2 个答案:

答案 0 :(得分:0)

无法将AsyncTask 中的值返回到主线程。有两种可能的解决方案

1)将您的文字视图设为全局变量,并在AsyncTask覆盖onPostExecute()。在帖子执行中,您可以使用服务器中的数据更新文本视图。

2)制作一个监听器(接口)。您的活动应该实现它并再次覆盖onPostExecute()并使用json数据调用该侦听器,最后在回调中使用json中的数据更新您的视图。

protected void onPostExecute(String result2) {
    try {
        String password1 = "";
        JSONArray jArray = new JSONArray(result);
        for (int i = 0; i < jArray.length(); i++) {
            json = jArray.getJSONObject(i);
            res=json.getString("status");
            break;
        }
        // UPDATE your views here, or make a callback to your class
        // via a listener and json data as a parameter and update 
        // your views there. Async tasks can cause memory leaks. 
        // Be careful with them.
    } catch (Exception e) {
    }
}

希望它有所帮助。

(PS - 只是一个提示,不要抓住一般例外,这是一个不好的做法)

此外,您可以将doInBackground的字符串传递给onPostExecute,该字符串由AsyncTask<String, String, String>的第3个参数决定。因此,由于您告诉它该对象属于String类型,您可以使用return null;调用中生成的字符串doInBackground替换null。

public class Json extends AsyncTask<String, String, String> {
    @Override
    protected void onPreExecute() {
    }

    @Override
    protected String doInBackground(String... params) {
        InputStream isr = null;
        String result;
        try {
            String URL = params[0];
            java.net.URL url = new URL(URL);
            URLConnection urlConnection = url.openConnection();
            isr = new BufferedInputStream(urlConnection.getInputStream());
        } catch (Exception e) {
            Log.e("log_tag", "error in http conection" + e.toString());
        }

        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(isr, "iso-8859-1"), 8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");

            }
            isr.close();
            result = sb.toString();
        } catch (Exception e) {
            Log.e("Log", "failed " + e.toString());
        }
        return result;
    }

    JSONObject json;
    protected void onPostExecute(String result) {
        try {
            String password1 = "";
            JSONArray jArray = new JSONArray(result);
            for (int i = 0; i < jArray.length(); i++) {
                json = jArray.getJSONObject(i);
                res=json.getString("status");

                break;
            }
        } catch (JSONArrayException ignored) {
        }
    }
}

我没有运行此代码。也许你可以检查和验证!

答案 1 :(得分:0)

执行是在另一个线程中,如果要在不在Json类中的活动中使用您重写t.setText(j.res);的活动中的结果,则可以在执行请求之前执行行onpostExecute如下:

new Json(){
@Override
protected void onPostExecute(String result2) {
//use string result as you want here   
}
}.execute("http://127.0.0.1/web/test.php");

并在doInBackGround中返回结果。不归null