Good day.

Through okhttp3 I make an asynchronous request:

client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { String jsonData = response.body().string(); try { JSONObject jobject = new JSONObject(jsonData); String id = jobject.getString("id"); //increment current id +1 String last_id = String.valueOf(Integer.parseInt(id)+1); Log.i("new id", last_id); if(response!=null){ response.getJsonResponse(last_id) } } catch (Exception e) { e.printStackTrace(); } //Log.i("ok", response.body().string()); } }); 

Interface for callback:

 public interface getResponse { void getJsonResponse(final String id); } 

And actually launching a request from the Activity:

 public class HomeActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Helper helper = new Helper(); helper.getLastId(new getResponse(){ @Override void getJsonResponse(String id){ } }); }} } 

I can't understand how to get an Activity object from getJsonResponse from which I made a request (for example, you need to change an arbitrary TextView).

I tried already throwing this in the helper.getLastId () call and on all callbacks, but it still does not work, although in the debugger you can see that the correct Activity comes in getJsonResponse ().

    2 answers 2

    Since the getResponse().getJsonResponse(String id) method is NOT executed in the main thread, because it is called in the thread executing the request, you cannot directly access the user interface elements in this method. Get the error that the user interface elements can only be accessed from the stream in which they were created, namely from the main stream.

    There are different ways to implement.

    In your case, with minimal changes in the code, in principle, you can do something like this using Handler

      public class HomeActivity extends AppCompatActivity { private Handler handler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); handler = new Handler(getMainLooper()); Helper helper = new Helper(); helper.getLastId(new getResponse(){ @Override void getJsonResponse(String id){ handler.post( new Runnable() { @Override public void run() { HomeActivity.this.textView.setText(id); } }); } ); } } 
    • Thank. Then it is generally easier to make Handler + a normal, non-asynchronous okhttp3 request. - Mikhail Mitrofanov

    Try running through HomeActivity.this.runOnUiThread

     public class HomeActivity extends AppCompatActivity { //объявляем TextView TextView tv_text; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //получаем TextView tv_text=findViewById(R.id.tv_text); Helper helper = new Helper(); helper.getLastId(new getResponse(){ @Override void getJsonResponse(String id){ //запуск в главном потоке HomeActivity.this.runOnUiThread(new Runnable() { public void run() { tv_text.setText(...); } }); } }); }} } 
    • The third option gives the error : 'E / AndroidRuntime: FATAL EXCEPTION: OkHttp Dispatcher Process: com.example.apps, PID: 11183 android.view.ViewRootImpl $ CalledFromWrongThreadException: You can touch the views. ............ at android.widget.TextView.checkForRelayout (TextView.java:8908) at android.widget.TextView.setText (TextView.java:5730) at android.widget.TextView.setText (TextView.java:5571) at android.widget.TextView.setText (TextView.java:5528) '—Michael Mitrofanov
    • The getResponse().getJsonResponse(String id) method is NOT executed in the main thread, it is called in the okhttp request okhttp , and therefore you cannot work with user interface elements. Easy way to use Handler or Broadcast to send messages - Vasil Baymurzin
    • Corrected the answer. Run through runOnUiThread. - virex-84