我想从回调中返回一个字符串
我的类在线程中从服务器获取日期,我希望主线程中的此值为字符串。我是Java的初学者。
public class InternetDate {
private final Activity activity;
private String finalDate = "";
public InternetDate(Activity activity) {
this.activity = activity;
}
public void setDateAndTimeFormat(String dateAndTimeFormat) {
mDateAndTimeFormat = dateAndTimeFormat;
}
public void getCurrentDate(OnGetDate onGetDate) {
new BackgroundTask(activity) {
@Override
public void doInBackground() {
try {
finalDate = getCurrentDateFromInternet();
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
@Override
public void onPostExecute() {
try {
JSONObject jb = new JSONObject(finalDate);
String name = jb.getString("UnixTimeStamp");
onGetDate.onSuccess(name);
if (progressDialog.isShowing()) {
progressDialog.dismiss();
}
} catch (JSONException e) {
}
}
}.execute();
}
private String getCurrentDateFromInternet() throws Exception {
String date_api = example.com/api;
URL url = new URL(date_api);
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(url.openStream()));
return in.readLine();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
}
}
}
public interface OnGetDate {
void onSuccess(String date);
}
我希望这是一个字符串。请帮我把这个字符串归档到MainThread
private String getDate(){
String currentDate = "";
InternetDate internetDate = new InternetDate(this);
internetDate.getCurrentDate(new InternetDate.OnGetDate() {
@Override
public void onSuccess(String date) {
currentDate = date; // Null return
}
});
return currentDate;
}
您可以使用信号量等待响应,但这种代码本质上是阻塞的,并导致应用程序具有糟糕的用户体验,因为ui线程在整个过程中被阻塞
//import java.util.concurrent.*;
//[...]
private String getDate() throws TimeoutException {
final String[] result = new String[]{null};
final Semaphore sem = new Semaphore(0);
new InternetDate(this).getCurrentDate(new InternetDate.OnGetDate() {
@Override
public void onSuccess(String date) {
result[0] = date; // Null return
sem.release();
}
});
try {
if (sem.tryAcquire(10, TimeUnit.SECONDS)) {
return result[0];
} else {
throw new TimeoutException("no response after 10 seconds");
}
} catch(InterruptedException e) {
return null;
}
}
您可以使用executor:
private String getDate() throws ExecutionException, InterruptedException {
// This line is non-blocking:
Future<String> future = Executors.newCachedThreadPool()
.submit(() -> new InternetDate().getCurrentDateFromInternet());
// The invocation of 'get' is blocking:
return future.get();
}
我假设getCurrentDateFromInternet
以您想要的格式返回日期。
您的问题可以使用mutableelvedata对象而不使用来解决阻塞UI线程
让我们开始假设你有一个名为MainThread
的主类,其中getDate
方法存在。
在这个类中首先创建以下MutableLiveData
对象:
private MutableLiveData<String> date = new MutableLiveData<>();
上面的对象将在程序可用时使用date值进行更新。
接下来创建/更新将调用getDate
方法的方法(为了简单起见,我们将保留该方法):
private void exampleDateMethod() {
// first create an observer; in the observer you put the code that does something with the Date
date.observe(this, new Observer<String>() {
@Override
public void onChanged( String date ) {
// this is where you do something with the date, an example:
findViewById( R.id.date_view ).setText( date );
}
});
// pass the MutableLiveData to the getDate method so that its value can be updated:
getDate( date );
}
并更改getDate
方法以将Date传递给mutableelivedata对象:
private void getDate( MutableLiveData<String> liveDate ){
internetDate.getCurrentDate(new InternetDate.OnGetDate() {
@Override
public void onSuccess(String date) {
// set the value of the MutableLiveData object, this will notify the observer and execute the code in its onChanged method
liveData.setValue( date );
}
});
}