Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/223.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Android上复制Swift完成处理程序&;JAVA_Java_Android_Ios_Google Cloud Firestore_Completionhandler - Fatal编程技术网

在Android上复制Swift完成处理程序&;JAVA

在Android上复制Swift完成处理程序&;JAVA,java,android,ios,google-cloud-firestore,completionhandler,Java,Android,Ios,Google Cloud Firestore,Completionhandler,几年后,我试图开发一款Android应用程序,使用Firebase Firestore。我基本上是想复制这个Swift功能: func getCategories(onCompletion completionBlock: @escaping (_ categories: [Category]?, _ error: Error?) -> Void) { firestore.collection("cats").getDocuments { (snap, error) in g

几年后,我试图开发一款Android应用程序,使用Firebase Firestore。我基本上是想复制这个Swift功能:

func getCategories(onCompletion completionBlock: @escaping (_ categories: [Category]?, _ error: Error?) -> Void) {

  firestore.collection("cats").getDocuments { (snap, error) in
    guard let snap = snap else {
      completionBlock(nil, error ?? anUnknownError)
      return
    }

    var categories: [Category] = []
    for document in snap.documents {
        let cat = Category.init(data: document.data())
        categories.append(cat)
    }
    completionBlock(categories, nil)
  }
}
但我不知道什么是斯威夫特积木的等价物,甚至不知道它是否存在

我检查了Firebase源代码
Query.get()

有什么帮助吗?多谢各位

编辑:添加了Android代码,以澄清我的意图

public class FirestoreService {

    private static volatile FirestoreService singleton = new FirestoreService();

    public static FirestoreService getInstance() {
        return singleton;
    }

    private FirebaseFirestore firestore() {
        // default firestore instance
        FirebaseFirestore db = FirebaseFirestore.getInstance();

        // default firestore settings
        FirebaseFirestoreSettings settings = db.getFirestoreSettings();

        // firestore settings builder
        FirebaseFirestoreSettings.Builder builder = new FirebaseFirestoreSettings.Builder(settings);

        // enable timstamps
        builder.setTimestampsInSnapshotsEnabled(true);

        // set new settings to db instance
        db.setFirestoreSettings(builder.build());


        // return db with new settings.
        return db;
    }



    public void getProductCategories(Handler? handler) {

       Task<QuerySnapshot> task = firestore().collection("coll").get();
       task.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
        @Override
        public void onComplete(@NonNull Task<QuerySnapshot> task) {
            try {
                if (task.isSuccessful()) {
                    List<Category> cats = new ArrayList<>();
                    for (QueryDocumentSnapshot doc : task.getResult()) {
                        String id = doc.getId();
                        Map<String, Object> data = doc.getData();
                        Category cat = new Category(id, data);
                        cats.add(cat);
                    }
                    // now I need completion handler
                } else {
                    Log.w("ERROR", "Error getting categories", task.getException());
                }
            } catch (Exception e) {
                Log.e("ERROR", e.getMessage());
            }
        }
    });
    }

}



public class MainActivity extends AppCompatActivity {

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

        FirestoreService.getInstance().getCategories().addCompletionListener(
            // handle List<Category> and respresent in UI
        );
    }
}
公共类FirestoreService{
私有静态易失性FirestoreService singleton=新FirestoreService();
公共静态FirestoreService getInstance(){
返回单身;
}
私有FirebaseFirestore firestore(){
//默认firestore实例
FirebaseFirestore db=FirebaseFirestore.getInstance();
//默认firestore设置
FirebaseFirestoreSettings=db.getFirestoreSettings();
//firestore设置生成器
FirebaseFirestoreSettings.Builder=新的FirebaseFirestoreSettings.Builder(设置);
//启用timstamps
builder.setTimeStampsSinSnapshotEnabled(true);
//将新设置设置为db实例
db.setFirestoreSettings(builder.build());
//返回带有新设置的数据库。
返回分贝;
}
public void getProductCategories(处理程序?处理程序){
任务=firestore().collection(“coll”).get();
task.addOnCompleteListener(新的OnCompleteListener(){
@凌驾
未完成的公共void(@NonNull任务){
试一试{
if(task.issusccessful()){
列表猫=新的ArrayList();
对于(QueryDocumentSnapshot文档:task.getResult()){
字符串id=doc.getId();
Map data=doc.getData();
类别cat=新类别(id、数据);
cats.add(cat);
}
//现在我需要完成处理器
}否则{
Log.w(“错误”,“获取类别时出错”,task.getException());
}
}捕获(例外e){
Log.e(“ERROR”,e.getMessage());
}
}
});
}
}
公共类MainActivity扩展了AppCompatActivity{
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FirestoreService.getInstance().getCategories().addCompletionListener(
//处理列表并在UI中重新呈现
);
}
}
使用异步任务 您可以使用
异步任务
。它有三个步骤

1.
onPreExecute()
-运行
doInBackground()之前要做的事情。这发生在UI主线程中。

2.
doInBackground()
-异步任务将在后台线程中执行操作(后台线程由Android创建,因此您无需担心)

3.
onPostExecute()
-在这里,您可以从doInBackground方法接收任何数据。postExecute方法将在UI主线程中再次执行。

因此,您可以在
doInBackground()
中执行任何I/O操作,并返回从服务器或任何其他数据源收到的值,
onPostExecute()
,相当于swift中的完成块

如何申报 要使用
AsyncTask
,您需要扩展Android
AsyncTask

因此,您自己的AsyncTask声明如下所示:

private class MyAsyncTask extends AsyncTask<Void, Void, Void> { ... }
在本例中,我创建了一个伪长操作,您不能在UI主线程上运行该操作(因为它是一个阻塞操作)

当操作完成时,它返回一个
字符串
,并且在
onPostExecute()
方法中接收到相同的字符串
(请记住,
onPostExecute()
再次在UI主线程上运行)。因此,您可以使用从长阻塞操作中收到的字符串值更改UI

如果您需要文档,请参阅:

使用观察者模式 您还可以在您的情况下使用观察者模式

创建一个接口,该接口有一个方法
onSuccess()。
让一个对象实现该接口,并且无论何时需要它,都可以调用
onSuccess()
方法

例如:

public Interface SuccessInterface{
   void onSuccess()
}

public class SuccessHandler implements SuccessInterface{
   public void onSuccess(){
         //success code goes here
   }

}

然后在您的代码中,实例化一个
SuccessHandler
,并在需要时调用
onSuccess()

非常感谢您的帮助和领导@Daniel-b

我现在已经解决了我的问题

首先,我创建了一个处理结果的界面;正如你所建议的

public interface ResultHandler<T> {
    void onSuccess(T data);
    void onFailure(Exception e);
}
公共接口ResultHandler{
成功时无效(T数据);
失效无效(例外情况e);
}
然后在服务类中,我将ResultHandler添加到函数的输入参数中:

public void getUserInfo(String id, ResultHandler<UserInfo> handler) {
    firestore().collection("userInfo").document(id).get().addOnCompleteListener(snap -> {
        if (snap.isSuccessful()) {
           try {
               // failable constructor. use try-catch
               UserInfo info = new UserInfo(snap.getResult().getId(), snap.getResult().getData());
               handler.onSuccess(info);
           } catch (Exception e) {
                handler.onFailure(e);
           }
        } else {
            handler.onFailure(snap.getException())
        }
    });
}
public void getUserInfo(字符串id,ResultHandler处理程序){
firestore().collection(“userInfo”).document(id).get().addOnCompleteListener(快照->{
if(snap.issusccessful()){
试一试{
//可失败的构造函数。请使用try-catch
UserInfo info=newuserinfo(snap.getResult().getId(),snap.getResult().getData());
handler.onSuccess(信息);
}捕获(例外e){
处理程序失败(e);
}
}否则{
handler.onFailure(snap.getException())
}
});
}
并在活动中调用服务

FirestoreService.getInstance().getUserInfo("ZsrAdsG5HVYLTZDBeZtkGDlIBW42", new ResultHandler<UserInfo>() {
    @Override
    public void onSuccess(UserInfo data) {
        Log.i("UserInfo", data.id);                    
    }

    @Override
    public void onFailure(Exception e) {
        // getting data failed for some reason
    }
});
FirestoreService.getInstance().getUserInfo(“ZsrAdsG5HVYLTZDBeZtkGDlIBW42”,新的ResultHandler(){
@凌驾
成功时公共无效(用户信息数据){
Log.i(“UserInfo”,data.id);
}
@凌驾
FirestoreService.getInstance().getUserInfo("ZsrAdsG5HVYLTZDBeZtkGDlIBW42", new ResultHandler<UserInfo>() {
    @Override
    public void onSuccess(UserInfo data) {
        Log.i("UserInfo", data.id);                    
    }

    @Override
    public void onFailure(Exception e) {
        // getting data failed for some reason
    }
});