如何同步2个异步线程/任务

时间:2017-05-08 17:41:27

标签: android asynchronous firebase android-asynctask firebase-realtime-database

对于我的应用程序,我必须运行两个操作,都是异步的:

  
      
  1. 从文件中读取(我使用此文件模拟从数据总线读取) - 异步操作因为我不知道“何时”到达新的   公共汽车上的消息/字符。我搜索一个特定的序列   字符,例如frame start_bytes =“xx”,后面的4个字节是   “数据”我等待。

  2.   
  3. 将数据读取/更新到Firebase,具体取决于从文件读取的“数据” - 由于使用addValueEventListener而导致的异步操作。

  4.   

我正在考虑一个信号量/互斥机制或一个简单的布尔标志,一个任务向另一个任务发出信号,表明新数据必须保存/更新到Firebase。

如何同步这两个操作(通过将它们嵌入Task / AsyncTask / Thread中)?

我搜索了这些主题,但我找到了与UI,ProgressBars等相关的示例..对我的情况不太适合/有用。

在Firebase中读取/更新数据

   myRefDevices.addValueEventListener(new ValueEventListener() {
                //  addValueEventListener
                // This method is called once with the initial value and again
                // whenever data at this location is updated.
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    boolean             bChildFound         = false;
                    DatabaseReference   dbrefChildFound;

                    final CDeviceStatus obj_new = new CDeviceStatus();

                    for( DataSnapshot val : dataSnapshot.getChildren() )
                    {
                        if( val.getKey().contentEquals(MAC_ADDRESS[ iIterator ]) )
                        {
                            bChildFound = true;

                            dbrefChildFound = val.getRef();

                            obj_new.setiAvailable_A( val.getValue( CDeviceStatus.class ).getiAvailable_A() + 1 );

                            obj_new.setsID(val.getValue( CDeviceStatus.class).getsID() );

                            dbrefChildFound.setValue(obj_new);
                        }
                    }

                    if(!bChildFound)
                    {
                        Log.d("child=" + MAC_ADDRESS[ iIterator ], "not found");
                    }


                    if(++iIterator == 16)
                    {
                        iIterator = 0;
                    }
                }

                @Override
                public void onCancelled(DatabaseError databaseError) {

                }

            });

从文件中读取:

try {
    // open input stream text file for reading
    Resources res = getResources();
    InputStream instream = res.openRawResource( R.raw.simulated_bus );

    //  we convert it to bufferred input stream
    BufferedInputStream bistreamSimulatedBus = new BufferedInputStream(instream);

        try{
            // if we want to stop reading from the file / simulated bus for whatever reason..
            boolean bStayInLoop         = true;

            while ((bistreamSimulatedBus.available() > 0) && bStayInLoop)
            {
                try {
                    // throw new InterruptedException();
                    char c = (char) bistreamSimulatedBus.read();

                    if( COUNT_CHARACTERS_NEWLINE )
                    {
                        if ( '\n' == c ){
                            //  we can count how much NewLine character we have
                            //iNL_Counter++;
                        }
                    } 

                ...

                }
                catch ( InterruptedException e ) {
                    throw new RuntimeException( e );
                }
            }
        } catch (IOException e) {
                throw new RuntimeException( e );
        } 
        finally {
                // release any resource associated with streams
                if ( null != instream ) {
                    instream.close();
                }

                if ( null != bistreamSimulatedBus ) {
                    bistreamSimulatedBus.close();
                }
            }
        }
    catch (Exception e) {
        throw new RuntimeException( e );
    }

谢谢。

1 个答案:

答案 0 :(得分:2)

让我们打破这样的解决方案:

基础知识

您有两项操作:o1o2。您希望第一个操作在第一个操作完成后立即执行。

显然在我看来,您需要event-driven解决方案。

<强>方法

使用Publisher/Subscriber设计模式的概念,您可以将Initiator的{​​{1}}设为事件的o1。然后,当完成此特定操作Publisher时,让类(活动,片段,服务)o1成为我们称之为notify的其他类。

<强>代码

将以下行添加到Subscriber

build.gradle (app-level)

然后,只需创建一个代表您的活动的简单compile 'org.greenrobot:eventbus:3.0.0' 即可。

Plain Old Java Object (POJO)

接下来,要public class RequestCompletedEvent{ // add constructor and anything you want} 该活动,您只需按此Publish拨打电话:

post(POJO instance)

然后,最后,在EventBus.getDefault().post(new RequestCompletedEvent(true)); 类中,只需通过添加以下代码行来监听通知:

Subscriber

然后仍然在同一个类中,使用@Override public void onStart() { super.onStart(); EventBus.getDefault().register(this); } @Override public void onStop() { super.onStop(); EventBus.getDefault().unregister(this); } 注释来捕获任何信号:

Subscribe

<强>摘要

这里有必要注意,最简单的方法是使用@Subscribe public void onEvent(RequestCompletedEvent event) { /* Do something */ //trigger the second operation here; startOperationTwo(); } 任务(AsyncTask子类)来读取文件,然后成功完成后,在async内,你可以通知onPostExecute()启动下一个操作。

我希望这会有所帮助;还有祝你好运!如果您需要进一步的帮助,请告诉我们!