Android - 在 UI 线程上同步调用线程

Android - Call Thread synchronized on UI thread

我尝试创建同步线程,但我总是收到以下错误:android.os.NetworkOnMainThreadException。

我阅读了更多帖子,但它们对我不起作用。

下面我写的代码块对我不起作用:

1.

final SyncApp syncJob = new SyncApp();
Thread t = new Thread (new Runnable () {
                         @Override
                         public void run () {
                             synchronized (syncJob) {
                                 String s = syncJob.insert (newJobs, GlobalVariables.URL_LOCALHOST + "jobs");
                                 txtState.setText (s);
                             }}});
                         }
                     });
                     t.Start ();
// t.run ();

2.

myClass.runOnUiThread(new Runnable() {
        public void run() {...}
})

3.

Running code in main thread from another thread

同步应用程序:

public class SyncApp {

    synchronized public String insert(List<Jobs> job, String... params) {
        URL url = null;
        HttpURLConnection conn = null;
        try {
            url = new URL(params[0]);
            conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setDoInput(true);
            conn.setDoOutput(true);
            String str = new Gson().toJson(job);
            byte[] outputInBytes = str.getBytes();
            OutputStream os = conn.getOutputStream();
            os.write( outputInBytes );
            os.flush();

            int responseCode=conn.getResponseCode();
            String response = null;
            if (responseCode == HttpsURLConnection.HTTP_OK) {
                String line;
                BufferedReader br=new BufferedReader(new InputStreamReader(conn.getInputStream()));
                while ((line=br.readLine()) != null) {
                    response+=line;
                }
            }
            else {
                response=conn.getResponseMessage();

            }
            return response;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            conn.disconnect();
        }
        return null;
    }
}

我需要调用一个线程,等待答案并调用另一个线程。他们的答案我必须在 activity

中使用它们

I need to call a thread, wait for the answer and call another thread. Their answers I must use them in the activity

使用异步任务完成的示例 objective。

在这段代码中,让 A 成为您需要调用线程的 activity, 等待答案并调用另一个线程。根据需要自定义。

由于您从不在 UI 个线程中等待,回调用于完成同步。

让 A 成为你的 activity class:

    public class A extends Activity {

       // some method in activity where you launch a background thread (B)
       // which then completes and invokes callback which then creates and launches
       // a background thread (C) which then completes and invokes a callback.
       //
       // In callback C, you are on the UI thread.
       protected void someMethod() {

          new B(new B.CallbackB() { 
             public void result(Object o) {
                new C(new C.CallbackC() {
                   public void result(Object o, Object answerFromB) {
                      // OK - C is now done and we are on UI thread!
                      //   'o' is answer from C
                      //   'answerFromB' also provided
                   }
                }, o).execute(new Object());
             }
          ).execute(new Object());
       }

    }

定义一个class B:

    public class B extends AsyncTask<Object, Void, Object> {

       public static interface CallbackB {
          void result(Object o);
       }

       private CallbackB cb;

       public B (CallbackB cb) {
          this.cb = cb;
       }

       protected Object doInBackground(Object... params) {
          // do work and return an answer.
          return new Object();
       }

       protected void onPostExecute(Object result) {
          if (cb != null) {
             cb.result(result);
          }
       }

    }

定义一个class C:

    public class C extends AsyncTask<Object, Void, Object> {

       public static interface CallbackC {
          void result(Object o, Object answerFromB);
       }

       private CallbackC cb;
       private Object answerFromB;

       public C (CallbackC cb, Object answerFromB) {
          this.cb = cb;
          this.answerFromB = answerFromB;
       }

       protected Object doInBackground(Object... params) {
          // do work and return an answer.
          return new Object();
       }

       protected void onPostExecute(Object result) {
          if (cb != null) {
             cb.result(result, answerFromB);
          }
       }

    }

供参考:

我的解决方案是:

public class Sync extends AppCompatActivity {

...

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_sync_server);

    dao = new DAO(this);

    txtState = findViewById(R.id.txt_log);

    btnSincro = findViewById(R.id.btn_sincro);
    btnSincro.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            countCall = 0;
            callFlow();
        }
    });

    btnHome = findViewById(R.id.btn_home);
    btnHome.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(SyncServerActivity.this, MainActivity.class);
            startActivity(intent);
        }
    });
}

private void callFlow() {
    switch (countCall) {

        case 0:
            templates = toTemplate("url");
            break;

        case 1:
            jobs = toJobs("url");
            break;

        case 2:
            job = ... //select item
            res = sendJobs(jobs, "url");
            break;

        default:
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    btnSincro.setEnabled(true);
                    txtState.append("\n\nEND");
                }
            });
    }
}

private void nextStep() {
    setText(txtState, "\nSync \n" + countCall + "/3");
    countCall++;
    callFlow();
}

private void setText(final TextView text, final String value) {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            text.setText(value);
        }
    });
}


public List<Templates> toTemplate(final String... params) {
    final List<Templates> list = new ArrayList<>();
    Thread t = new Thread(new Runnable() {
        @Override
        public void run() {
            URL url = null;
            BufferedReader reader = null;
            HttpURLConnection connection = null;

            try {
                url = new URL(params[0]);
                connection = (HttpURLConnection) url.openConnection();
                connection.connect();

                InputStream stream = connection.getInputStream();

                reader = new BufferedReader(new InputStreamReader(stream));

                int responseCode = connection.getResponseCode();
                String response = null;
                if (responseCode == HttpsURLConnection.HTTP_OK) {
                    StringBuffer buffer = new StringBuffer();
                    String line = "";
                    while ((line = reader.readLine()) != null) {
                        buffer.append(line);
                    }
                    String finalJson = buffer.toString();
                    JSONObject parentObject = new JSONObject(finalJson);
                    JSONArray parentArray = parentObject.getJSONArray("data");
                    for (int i = 0; i < parentArray.length(); i++) {
                        Templates item = new Gson().fromJson(parentArray.get(i).toString(), Templates.class);
                        list.add(item);
                    }
                } else {
                    response = connection.getResponseMessage();
                }

            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            } finally {
                if (connection != null)
                    connection.disconnect();
                try {
                    if (reader != null)
                        reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                nextStep(); //call next Thread
            }
        }
    });
    t.start();
    return list;
}

public List<Jobs> toJobs(final String... params) {
    final List<Jobs> list = new ArrayList<>();
    Thread t = new Thread(new Runnable() {
        @Override
        public void run() {
            URL url = null;
            BufferedReader reader = null;
            HttpURLConnection connection = null;
            try {
                url = new URL(params[0]);
                connection = (HttpURLConnection) url.openConnection();
                connection.connect();

                InputStream stream = connection.getInputStream();

                reader = new BufferedReader(new InputStreamReader(stream));

                int responseCode = connection.getResponseCode();
                String response = null;
                if (responseCode == HttpsURLConnection.HTTP_OK) {
                    StringBuffer buffer = new StringBuffer();
                    String line = "";
                    while ((line = reader.readLine()) != null) {
                        buffer.append(line);
                    }
                    String finalJson = buffer.toString();
                    JSONObject parentObject = new JSONObject(finalJson);
                    JSONArray parentArray = parentObject.getJSONArray("data");
                    for (int i = 0; i < parentArray.length(); i++) {
                        Jobs item = new Gson().fromJson(parentArray.get(i).toString(), Jobs.class);
                        list.add(item);
                    }
                } else {
                    response = connection.getResponseMessage();
                }

            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            } finally {
                if (connection != null)
                    connection.disconnect();
                try {
                    if (reader != null)
                        reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                nextStep();
            }
        }
    });
    t.start();
    return list;
}

public Boolean sendJobs(final List<Jobs> job, final String... params) {
    final Boolean[] result = {false};
    Thread t = new Thread(new Runnable() {

        @Override
        public void run() {
            URL url = null;
            HttpURLConnection conn = null;
            try {
                url = new URL(params[0]);
                conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("POST");
                conn.setRequestProperty("Content-Type", "application/json");
                conn.setDoInput(true);
                conn.setDoOutput(true);
                String str = new Gson().toJson(job);
                Log.d(TAG, str);
                byte[] outputInBytes = str.getBytes();
                OutputStream os = conn.getOutputStream();
                os.write(outputInBytes);
                os.flush();

                int responseCode = conn.getResponseCode();
                String response = null;
                if (responseCode == HttpsURLConnection.HTTP_OK) {
                    String line;
                    BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                    while ((line = br.readLine()) != null) {
                        response += line;
                    }
                    result[0] = true;
                } else {
                    response = conn.getResponseMessage();
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                conn.disconnect();
                nextStep();
            }
        }
    });
    t.start();
    return result[0];
}
}

每当线程结束时,它都会调用 nextStep() 方法,该方法会启动下一个 trhead。