0

thread.join我在下面的代码中使用时遇到问题。它应该等待线程完成,然后再执行它之后的代码,对吧?它在不同的场合表现不同。

我有三个案例来检查我的代码是否运行良好

  • 应用程序第一次使用 - 按预期工作,但下载时加载页面不出现
  • 应用程序被第二次使用(数据库是最新的) - 工作正常
  • 应用程序第三次使用(数据库已过时,必须更新) - 不会更新,屏幕黑屏,然后崩溃

我认为我在方法上的代码有问题onCreate

dropOldSchedule();
dropThread.join();
triggerDownload();

根据日志,代码在这部分之前一直有效......可能是什么问题?


MainActivity.java

public class MainActivity extends Activity {

final static int INDEX_ACCTTYPE = 0; 
final static int INDEX_ECN = 1; 
final static int INDEX_TLN = 2; 
final static int INDEX_SIN = 3; 
final static int INDEX_MOBILE = 4; 
final static int INDEX_CITY = 5;
final static int INDEX_START_DATE = 6;
final static int INDEX_START_TIME = 7;
final static int INDEX_END_DATE = 8; 
final static int INDEX_END_TIME = 9; 
final static int INDEX_REASON = 10;
final static int INDEX_DETAILS = 11;

DatabaseHandler db;
String str;
ProgressDialog pd;

TextView homeText1, homeText2, homeText3, homeText4;

final private String csvFile = "http://www.meralco.com.ph/pdf/pms/pms_test.csv";
final private String uploadDateFile = "http://www.meralco.com.ph/pdf/pms/UploadDate_test.txt";

Thread dropThread = new Thread(new Runnable() {

    public void run() {
        db = new DatabaseHandler(MainActivity.this);
        db.dropOldSchedule(); 

        runOnUiThread(new Runnable() {
            public void run() {
                while (!pd.isShowing());
                db.close();
                pd.dismiss();
            }
        });
    }

});
Thread getUploadDateThread = new Thread(new Runnable() {

    public void run() {

        try {
            URL myURL = new URL(uploadDateFile);

            BufferedReader so = new BufferedReader(new InputStreamReader(myURL.openStream()));
            while (true) {
                String output = so.readLine();
                if (output != null) {
                    str = output;
                }
                else {
                    break;
                }
            }
        so.close();
        }
        catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } 

        runOnUiThread(new Runnable() {
            public void run() {
                while (!pd.isShowing());
                pd.dismiss();
            }
        });
    }

    });
Thread downloadThread = new Thread(new Runnable() {

    public void run() {

        db = new DatabaseHandler(MainActivity.this);
        db.beginTransaction();

        try {
            URL url = new URL(csvFile);

            Log.i("dl", "start");

            InputStream input = url.openStream();
            CSVReader reader = new CSVReader(new InputStreamReader(input));
            Log.i("dl", "after reading");

            String [] sched;
            while ((sched = reader.readNext()) != null) {
                if(sched[INDEX_CITY].equals("")) sched[INDEX_CITY]="OTHERS";
                try {

                    db.addRow(sched[INDEX_SIN], sched[INDEX_CITY], 
                            sched[INDEX_START_DATE], sched[INDEX_START_TIME], 
                            sched[INDEX_END_DATE], sched[INDEX_END_TIME], 
                            sched[INDEX_DETAILS], sched[INDEX_REASON]);
                } catch (IndexOutOfBoundsException e) {
                    db.addRow(sched[INDEX_SIN], sched[INDEX_CITY], 
                            sched[INDEX_START_DATE], sched[INDEX_START_TIME], 
                            sched[INDEX_END_DATE], sched[INDEX_END_TIME], 
                            "", sched[INDEX_REASON]);
                    //e.printStackTrace();
                }
            }
            input.close();
            Log.i("dl", "finished");

        } catch (MalformedURLException e) {
            e.printStackTrace();
            db.endTransaction();
        } catch (IOException e) {
            e.printStackTrace();
            db.endTransaction();
        } 
        Log.d("Count", ""+db.count());
        db.setTransactionSuccessful();
        db.endTransaction();

        writeUploadDateInTextFile();

    }

});

@SuppressWarnings("unqualified-field-access")
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.pms_main);

    Button home = (Button) findViewById(R.id.home);
    home.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            Intent intent = new Intent(MainActivity.this, MeralcoSuite_TabletActivity.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(intent);

            finish();
        }
    });

    homeText1 = (TextView) findViewById(R.id.home_text1);
    homeText2 = (TextView) findViewById(R.id.home_text2);
    homeText3 = (TextView) findViewById(R.id.home_text3);
    homeText4 = (TextView) findViewById(R.id.home_text4);

    homeText1.setVisibility(View.INVISIBLE);
    homeText2.setVisibility(View.INVISIBLE);
    homeText3.setVisibility(View.INVISIBLE);
    homeText4.setVisibility(View.INVISIBLE);

    getUploadDate();
    try {
        getUploadDateThread.join();     //wait for upload date

        Log.d("getUploadDate","thread died, upload date=" + str);

        if(dbExists()){
            db = new DatabaseHandler(MainActivity.this);
            Log.d("Count", "" + db.count());
            db.close();

            if(!uploadDateEqualsDateInFile()){
                dropOldSchedule();
                    dropThread.join();
                triggerDownload();
            }
            showDisclaimer();
            Log.i("oncreate", "finished!");
            return;
        }

        triggerDownload();
        showDisclaimer();
        Log.i("oncreate", "finished!");

    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

public void dropOldSchedule(){

    if(pd!=null && pd.isShowing())
        pd.setTitle("Getting upload date...");
    else
        pd = ProgressDialog.show(this, "Getting upload date", 
            "This may take a few minutes...", true, false);


    dropThread.start();
}
public void triggerDownload() {

    if (!checkInternet()) {
        showAlert("An internet connection is required to perform an update, please check that you are connected to the internet");
        return;
    }

    if(pd!=null && pd.isShowing())
        pd.setTitle("Getting upload date...");
    else
        pd = ProgressDialog.show(this, "Getting upload date", 
            "This may take a few minutes...", true, false);

    downloadThread.start();

}

public void getUploadDate() {

    Log.d("getUploadDate", "getting upload date of schedule");

    if(pd!=null && pd.isShowing())
        pd.setTitle("Getting upload date...");
    else
        pd = ProgressDialog.show(this, "Getting upload date", 
            "This may take a few minutes...", true, false);


    getUploadDateThread.start();

}

public void writeUploadDateInTextFile() {
    Log.d("writeUploadDateTextFile", "writing:"+str);

    try {
        OutputStreamWriter out = new OutputStreamWriter(openFileOutput(
                "update.txt", 0));
        out.write(str);
        out.close();
    } catch (java.io.IOException e) {
        e.printStackTrace();
    }
}

public void showDisclaimer() {
    Log.d("ShowDisclaimer", "showing disclaimer");

    homeText3
    .setText("..." + str
            + "...");


    homeText1.setVisibility(View.VISIBLE);
    homeText2.setVisibility(View.VISIBLE);
    homeText3.setVisibility(View.VISIBLE);
    homeText4.setVisibility(View.VISIBLE);

    Log.d("showDisclaimer", "finished showing disclaimer");

}

public boolean uploadDateEqualsDateInFile() {
    Log.d("uploadDateEqualsDateInFile","comparing schedule upload dates");

    try {
            String recordedDate = "";
            InputStream instream = openFileInput("update.txt");
            if (instream != null) { // if file the available for reading
                Log.d("uploadDateEqualsDateInFile","update.txt found!");

                InputStreamReader inputreader = new InputStreamReader(instream);
                BufferedReader buffreader = new BufferedReader(inputreader);

                String line = null;
                while ((line = buffreader.readLine()) != null) {
                    recordedDate = line;
                    Log.d("uploadDateEqualsDateInFile","recorded:"+recordedDate);
                }

                Log.d("uploadDateEqualsDateInFile","last upload date: " + str + ", recorded:" +recordedDate);

                if(str.equals(recordedDate)) return true;
                return false;
            }
            Log.d("uploadDateEqualsDateInFile","update.txt is null!");
            return false;   

    } catch (FileNotFoundException e) {
        e.printStackTrace();
        return false;
    } catch (IOException e) {
        e.printStackTrace();
        return false;
    }
}

public boolean checkInternet() {
    ConnectivityManager cm = (ConnectivityManager) this
            .getSystemService(Context.CONNECTIVITY_SERVICE);

    NetworkInfo infos[] = cm.getAllNetworkInfo();

    for (NetworkInfo info : infos)
        if (info.getState() == NetworkInfo.State.CONNECTED
                || info.getState() == NetworkInfo.State.CONNECTING) {
            return true;
        }

    return false;
}

public boolean dbExists() {

    File database=getApplicationContext().getDatabasePath(DatabaseHandler.DATABASE_NAME);

    if (!database.exists()) {
        Log.i("Database", "Not Found");
        return false;
    }

    Log.i("Database", "Found");
    return true;

}

@Override
protected void onDestroy() {
    super.onDestroy();
    if (db != null) {
        db.close();
    }
}
@Override
protected void onPause() {
    super.onPause();
    if (db != null) {
        db.close();
    }
}

}

4

3 回答 3

2

抱歉,我在您的代码中找不到错误或问题。但我强烈建议您使用 AsyncTask 在不同的线程中执行某些操作。AsyncTask 非常易于使用,我想说它是 java 的最大优势之一。我真的很想念obj-c。

http://labs.makemachine.net/2010/05/android-asynctask-example/

http://marakana.com/s/video_tutorial_android_application_development_asynctask_preferences_and_options_menu,257/index.html

检查这些链接希望对您有所帮助。

于 2012-07-31T12:18:48.520 回答
1

已经提到这AsyncTask是更好的选择。但是,您的 join 调用可能会抛出InterruptedException. 尝试像这样使用它:

while(getUploadDateThread.isRunning()){
    try{
        getUploadDateThread.join();
    } catch (InterruptedException ie){}
}
// code after join
于 2012-07-31T12:52:30.153 回答
0

我认为您面临的问题是您在onCreate()方法中调用 join 时阻塞了 UI 线程。您应该将此代码移动到另一个应该在后台执行的线程中,一旦完成,您就可以更新 UI。

这是一个示例代码:

    final Thread t1 = new Thread();
    final Thread t2 = new Thread();
    t1.start();
    t2.start();
    new Thread(new Runnable() {

        @Override
        public void run() {
            // Perform all your thread joins here.
            try {
                t1.join();
                t2.join();
            } catch (Exception e) {
                // TODO: handle exception
            }


            // This thread wont move forward unless all your threads
            // mentioned above are executed or timed out.
            // ------ Update UI using this method
            runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    // Update UI code goes here

                }
            });

        }
    }).start();
于 2014-02-25T07:46:02.250 回答