0

请参阅底部的修订这是一张战斗卡,因此它有两个人互相战斗,红色对蓝色。它必须是一个动态列表,其中包含来自 parse.com 的填充信息。第一个查询是fightOrder。这是 Parse.com 上的一个类,其中有两个objectId's 在一行中。redCorner并在我的blueCorner数据库(也在 parse.com)中找到此信息并相应地显示信息。我的问题是我的progressDialog盒子出现了,而且它永远不会消失。我的名单永远不会被填充。我尝试在没有对话框的情况下执行此操作,并用曾经的查询填充我的列表并得到相同的结果。

注意:该列表工作正常。这是我以前成功使用过的列表,当时我会以不同的方式加载我的信息。我只是在改变加载信息的方式,因为我需要一个包含所有战士的数据库,并从该列表中加载我的战斗卡。

注意: GetCallBack并且FindCallBack是异步的,这就是为什么这是一个奇怪的循环。我必须等待done()

这里是java

public class databaseFightCard extends Activity {
int I;
int size;
private HomeListAdapter HomeListAdapter;
private ArrayList<HomeItem> HomeItemList;
private SeparatedListAdapter adapter;

//this int is to test for main and coMain events. If one is TRUE, It will assign the array position to main or coMain.
int main, coMain;
ParseQuery<ParseObject> blueCorner = ParseQuery.getQuery("FightersDB");
ParseQuery<ParseObject> redCorner = ParseQuery.getQuery("FightersDB");

String name1, name2;
List<String> red = new ArrayList<String>();
List<String> blue = new ArrayList<String>();
private ListView listView;

ProgressDialog progressDialog;

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

   progressDialog = ProgressDialog.show(this, "", "Loading bout...", true);

    initialization();

    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

            HomeItem homeItem = (HomeItem) adapter.getItem(position);

            AlertDialog.Builder showFighter = new AlertDialog.Builder(databaseFightCard.this, android.R.style.Theme_DeviceDefault_Dialog);

            showFighter.setTitle(homeItem.getHomeItemLeft().toString() + " and " + homeItem.getHomeItemRight().toString());
            showFighter.setMessage("166 - 165\nLogan Utah - Richmond Utah");
            showFighter.setPositiveButton("DONE", null);
            showFighter.setNegativeButton("Cancel", null);
            AlertDialog dialog = showFighter.show();
            TextView messageView = (TextView) dialog.findViewById(android.R.id.message);
            messageView.setGravity(Gravity.CENTER);


            Toast.makeText(getBaseContext(), homeItem.getHomeItemLeft().toString() + " " + homeItem.getHomeItemRight().toString(), Toast.LENGTH_LONG).show();
            System.out.println("Selected Item : " + homeItem.getHomeItemID());
        }
    });


    HomeListAdapter = new  HomeListAdapter(getApplicationContext(), 0, HomeItemList);


    //find the fight card, and read the ids
    ParseQuery<ParseObject> fightOrder = ParseQuery.getQuery("FightCard");
    fightOrder.findInBackground(new FindCallback<ParseObject>() {
        @Override
        public void done(List<ParseObject> parseObjects, ParseException e) {
            if (e == null) {
                size = parseObjects.size();
                int i = 0;


                while (i < size) {
                    if (parseObjects.get(i).getBoolean("main")) {
                        main = i;
                    }

                    if (parseObjects.get(i).getBoolean("coMain")) {
                        coMain = i;
                    }
                    red.add(i, parseObjects.get(i).getString("redCorner"));
                    blue.add(i, parseObjects.get(i).getString("blueCorner"));
                    i++;
                }

                displayRed();


            } else {
                e.printStackTrace();
            }
        }
    });

}



private void displayRed() {


    adapter = new SeparatedListAdapter(this);

    //find one fighter at a time. in the done() method, start the second fighter.

        redCorner.getInBackground(red.get(I), new GetCallback<ParseObject>() {
            @Override
            public void done(ParseObject parseObject, ParseException e) {
                if (e == null) {
                    HomeItemList = new ArrayList<HomeItem>();
                    HomeItem homeItem = new HomeItem();
                    homeItem.setHomeItemID(I);
                    name1 = parseObject.getString("Name");
                    homeItem.setHomeItemLeft(name1);
                    HomeItemList.add(homeItem);
                    if (HomeListAdapter != null) {
                        if (I == main) {
                            adapter.addSection(" MAIN EVENT ", HomeListAdapter);
                        } else if (I == coMain) {
                            adapter.addSection(" Co-MAIN EVENT ", HomeListAdapter);
                        } else {
                            adapter.addSection(" FIGHT CARD ", HomeListAdapter);
                        }
                    }
                  displayBlue();
                } else {
                    e.printStackTrace();
                }
                I++;
                while (I < size){
                    displayRed();
                }
                if (size == I) {
                    listView.setAdapter(adapter);

                    progressDialog.dismiss();
                }

            }
        });
    }




private void displayBlue() {



    //find the red fighters then call the dismiss();

    blueCorner.getInBackground(blue.get(I), new GetCallback<ParseObject>() {
        @Override
        public void done(ParseObject parseObject, ParseException e) {
            if (e == null) {
                HomeItemList = new ArrayList<HomeItem>();
                HomeItem homeItem = new HomeItem();
                homeItem.setHomeItemID(I);
                name2 = parseObject.getString("Name");
                homeItem.setHomeItemLeft(name2);
                HomeItemList.add(homeItem);
                if (HomeListAdapter != null) {
                    if (I == main) {
                        adapter.addSection(" MAIN EVENT ", HomeListAdapter);
                    } else if (I == coMain) {
                        adapter.addSection(" Co-MAIN EVENT", HomeListAdapter);
                    } else {
                        adapter.addSection(" FIGHT CARD ", HomeListAdapter);
                    }
                }

            } else {
                e.printStackTrace();
            }
            //if it is done running through all the IDS, set the listView, and dismiss the dialog.


            I++;
            while (I < size){
                displayRed();
            }
            if (size == I) {
                listView.setAdapter(adapter);

               progressDialog.dismiss();
            }
        }
    });
}


private void initialization() {
    listView = (ListView) findViewById(R.id.Listview);
}

日志猫

java.lang.RuntimeException:此查询具有未完成的网络连接。你必须等到它完成。

那是指向这条线:

   while (I < size){
                    displayRed();
                }

编辑

我相信这是导致这种情况的异步任务。

在以前的构建中:我会一次调用一个行项目,将其添加到我的列表中,重复直到完成,然后显示列表。

在这个版本上:我想调用redCorner将它添加到我的列表,调用blueCorner 将它添加到同一行,重复直到完成,然后显示列表。这是它的样子(以前的版本):

战斗卡


修订我的问题仍然没有答案。也许我需要简化它。一节课我会得到+-20 objectId's。我去掉了所有不相关的代码。使用此代码仍然会得到意想不到的结果。

       redCorner.getInBackground(red.get(i), new GetCallback<ParseObject>() {
            @Override
            public void done(ParseObject parseObject, ParseException e) {
                if (e == null) {

                    Log.d("NAME " + i, name1 + " ");

                    i++;
                    while (i < size) {
                        redCorner.cancel();
                        displayRed();
                    }
                    if (i == size) {
                        progressDialog.dismiss();
                    }

                } else {
                    e.printStackTrace();
                }
            }
        });
4

1 回答 1

2

这是不了解异步编码本质的又一个案例(我已经看到很多关于同一问题的问题)。

在您的情况下,您正在调用displayRed()触发一些异步代码然后返回的方法。

以下是您的代码可能运行的方式:

  • 第一次调用displayRed()(dr1)
    • (dr1) 异步redCorner.getInBackground(..)(async1) 已启动
    • (dr1) 返回
  • ..一段时间过去了..
  • (async1)getInBackground(..)调用返回数据,运行代码块
    • 调用displayBlue()(db1)
      • (db1) blueCorner.getInBackground(..)(async2) 已启动
      • (db1) 返回
    • 开始while循环
      • 来电displayRed()(dr2)
        • (dr2) 异步redCorner.getInBackground(..)(async3) 已启动
        • (dr2) 什么都没有触及I,尝试启动另一个异步redCorner.getInBackgroud(..)(async4)
        • 错误

您正在编写代码,就好像异步块正在运行同步一样。请记住,这getInBackground意味着“进行网络调用以获取此数据,并在发生某些事情(错误或成功)时运行我给您的这段代码,可能在另一个线程上”。

想想你想要实现的顺序,意识到你要求它开始一个需要一些时间的过程,并相应地调整你的代码。

于 2013-10-01T23:53:27.907 回答