2016-06-16 6 views
0

Я пытаюсь подключить свое приложение к базе данных Mysql с помощью JSON и PHP. PHP-скрипт возвращает массив JSON, который определяет статус света (true или false).Передача данных JSON в основное действие

Я попытался поместить код JSON, который открывает соединение URL и получает статус в отдельном классе. В результате я могу называть его всякий раз, когда мне нужно его использовать.

Проблема заключается в том, что переменная res имеет значение внутри класса JSON, но когда я попытался получить к ней доступ из основного действия с использованием объекта JSON, он пуст. Может ли кто-нибудь направить меня к правильному решению проблемы?

Основная деятельность

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 класс

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) { 

    } 
    } 
} 
+0

't.setText (j.res);' происходит до того, как задача Async завершает выполнение. Все манипуляции с пользовательским интерфейсом должны выполняться через 'onPostExecute' – jitinsharma

+0

@ muthana1990 да, вы должны это сделать, а не возвращать null в doinback ground, как показано в моем ответе –

+0

Я обновил мои ан, если это имеет смысл. –

ответ

0

Вы не может возвращать значение из AsyncTask в основном потоке, как это. Существует 2 возможных решения:

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, которая решается на 3 параметра вашей AsyncTask<String, String, String>. поэтому, поскольку вы говорите ему, что объект должен быть String, вы можете return null; заменить null на строку, сгенерированную в вашем вызове doInBackground.

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) { 
     } 
    } 
} 

Я не запускал этот код. Может быть, вы можете проверить и проверить!

+0

Работает. Большое спасибо. – jack

+0

most welcome :) –

+0

Я попытался использовать первое решение, и я объявил textView как глобальную переменную, но не предлагает, когда я пытался использовать его внутри onPostExecute(). – jack

0

исполнение в другом потоке, и это может быть выполнить линию t.setText(j.res); перед выполнением запроса, если вы хотите использовать результат в деятельности вы канд переопределения onpostExecute в деятельности не в классе Json следующим образом:

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. not return null

+0

Также работает. отлично сработано. Спасибо. – jack

Смежные вопросы