重新打开封闭对象错误 - Android

时间:2012-07-25 21:45:43

标签: android testing sqlite

我正在使用SQLite数据库对应用程序运行一些测试。我在创建默认活动时调用open,然后testSuite()方法在完成测试后将其关闭。但是,同一行不断给我一个错误,告诉我该对象已关闭,我正在尝试重新打开它。我不知道这种关闭可能发生在哪里,而且我是那些经常无法证明自己的代码的人之一。有谁介意我为什么会收到这个错误?

public class SQLTest extends Activity
{
public SQLAdapter adapter;
public int[] bb_count;

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    bb_count = new int[21];
    bb_count[0]++;
    setContentView(R.layout.activity_sqltest);
    adapter = new SQLAdapter(this);
    adapter.createDatabase();
    open();
}

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
    bb_count[1]++;
    getMenuInflater().inflate(R.menu.activity_sqltest, menu);
    return true;
}

public SQLAdapter accessAdapter()
{
    bb_count[2]++;
    return adapter;
}

public void open()
{
    bb_count[3]++;
    adapter.open();
}

public void close()
{
    bb_count[4]++;
    adapter.close();
}

public long insert(String name, String field)
{
    bb_count[5]++;
    long id = adapter.insert(name, field);
    return id;
}

public long insert(int id, String name, String field)
{
    bb_count[5]++;
    id = (int) adapter.insert(id, name, field);
    return id;
}

public int delete(int id)
{
    bb_count[7]++;
    int rowsDeleted = adapter.delete(id);
    return rowsDeleted;
}

public int update(int id, String name, String field)
{
    bb_count[8]++;
    int rowsUpdated = adapter.update(id, name, field);
    return rowsUpdated;
}

public boolean get(Cursor cursor, int id)
{
    bb_count[9]++;
    try
    {
        bb_count[10]++;
        cursor = adapter.get(id);
        TextView tv = new TextView(this);
        String table = "";
        if (cursor.moveToFirst())
        {
            bb_count[11]++;
            table += "\n" + cursor.getString(0) + " " + cursor.getString(1) + " " + cursor.getString(2);
        }
        else
        {
            bb_count[12]++;
            table += "No hall found with ID: " + id;
            return false;
        }
        tv.setText(table);
        setContentView(tv);
    } catch (Exception e) {
        bb_count[13]++;
    }
    return true;
}

public boolean getAll(Cursor cursor)
{
    bb_count[14]++;
    try
    {
        bb_count[15]++;
        TextView tv = new TextView(this);
        String table = "";
        try
        {
            bb_count[16]++;
            cursor = adapter.getAll();
            if (cursor.moveToFirst())
            {
                bb_count[17]++;
                do
                {
                    bb_count[18]++;
                    table += "\n" + cursor.getString(0) + " " + cursor.getString(1) + " " + cursor.getString(2);
                } while (cursor.moveToNext());
            }
        } catch (Exception e) {
            bb_count[19]++;
        }
        tv.setText(table);
        setContentView(tv);
    } catch (Exception e) {
        bb_count[20]++;
        return false;
    }
    return true;
}

public String blockCoverage()
{
    String coverage = "";
    for (int x = 0; x < bb_count.length; x++)
        coverage += x + " " + bb_count[x] + "\n";
    return coverage;
}
}

public class SQLSuiteVer2 extends ActivityInstrumentationTestCase2<SQLTest>
{
SQLTest activity;

public SQLSuiteVer2()
{
    super(SQLTest.class);
}

protected void setUp() throws Exception
{
    super.setUp();
    setActivityInitialTouchMode(false);
    activity = getActivity();
}

public void testPreConditions()
{
    assertTrue(activity.accessAdapter() != null);
    assertTrue(activity.accessAdapter().accessHelper().checkDatabase());
}

public void testSuite() throws IOException
{
    int length = 100;
    Cursor[] cursors = new Cursor[5];
    for (int x = 0; x < 5; x++)
        cursors[x] = activity.accessAdapter().getAll();

    for (int x = 0; x < length; x++)
    {
        randomTest(cursors);
    }
    System.out.println( activity.blockCoverage()
            + activity.accessAdapter().accessHelper().blockCoverage());
    for (int x = 0; x < 5; x++)
        cursors[x].close();
    activity.close();
}

public void testInsert(Cursor cursor, String name, String field)
{

    int id = (int) activity.insert(name, field);
    assert (activity.get(cursor, id));
}

public void testDelete(Cursor cursor, int id)
{
    try
    {   
        activity.delete(id);
        assert (!activity.get(cursor, id));
    } catch (Exception e) {
        throw new Error("Row doesn't exist.");
    }
}

public void testUpdate(int id, String name, String field)
{
    Cursor cursor = activity.accessAdapter().get(id);
    activity.update(id, name, field);
    Cursor cursor2 = activity.accessAdapter().get(id);
    assertTrue(!(cursor.equals(cursor2)));
}

public void testGet(Cursor cursor, int id)
{
    assert activity.get(cursor, id);
}

public void testGetAll(Cursor cursor)
{
    assert activity.getAll(cursor);
}

public void testJoin(Cursor cursor, Cursor cursor2)
{
    String table = SQLAdapter.TABLE_OS;
    String sql = "CREATE TABLE Blah"
        + "_id INTEGER PRIMARY KEY AUTOINCREMENT, "
        + "OrderNo. INTEGER NOT NULL, "
        + "Item TEXT NOT NULL)";
    try
    {
        cursor = activity.accessAdapter().accessHelper().accessDatabase().rawQuery(sql, null);
    } catch (Exception e) {
        throw new Error("Could not make new 'Blah' table.");
    }
    sql = "SELECT * FROM " + table + " FULL JOIN Blah ON "
            + table + "._id=Blah._id";
    try
    {
        cursor2 = activity.accessAdapter().accessHelper().accessDatabase().rawQuery(sql, null);
    } catch (Exception e) {
        throw new Error("Could not join 'Blah' and '" + table + "' tables.");
    }
}

public void testJoinCopy(Cursor cursor, Cursor cursor2)
{
    String table = SQLAdapter.TABLE_OS;
    String sql = "SELECT * FROM " + table + " FULL JOIN " + table + "2 ON "
            + table + "._id=" + table + "2._id";

    cursor = activity.accessAdapter().getAll();
    try
    {
        cursor2 = activity.accessAdapter().accessHelper().accessDatabase().rawQuery(sql, null);
    } catch (Exception e) {
        throw new Error("Could not join '" + table +"' and its copy.");
    }

}

public void testJoinUnrelated(Cursor cursor, Cursor cursor2)
{
    String table = SQLAdapter.TABLE_OS;
    String sql = "CREATE TABLE Blah2"
            + "Name TEXT PRIMARY KEY, "
            + "OrderNo. INTEGER NOT NULL, "
            + "Item TEXT NOT NULL)";
    try
    {
        cursor = activity.accessAdapter().accessHelper().accessDatabase().rawQuery(sql, null);
    } catch (Exception e) {
        throw new Error("Could not make new 'Blah' table.");
    }

    sql = "SELECT * FROM " + table + " FULL JOIN Blah ON "
            + table + "._id=Blah._id";
    try
    {
        cursor2 = activity.accessAdapter().accessHelper().accessDatabase().rawQuery(sql, null);
    } catch (Exception e) {
        throw new Error("Could not join two tables without a similar '_id'.");
    }
}

public void testOverWrite(Random rand, String name, String field)
{
    int id;
    do
    {
        id = rand.nextInt();
    } while (activity.accessAdapter().get(id) == null);

    Cursor cursor = activity.accessAdapter().get(id);
    activity.insert(id, name, field);
    Cursor cursor2 = activity.accessAdapter().get(id);
    assertTrue(!(cursor.equals(cursor2)));
}

@SuppressLint("NewApi")
public void randomTest(Cursor[] cursors)
{
    String name = "", field = "";
    Random rand = new Random();
    int randOp = rand.nextInt(9);
    int randName, randField, id;

    Cursor cursor = activity.accessAdapter().getAll();
    cursor.moveToFirst();
    int start = Integer.parseInt(cursor.getString(0));
    cursor.moveToLast();
    int end = Integer.parseInt(cursor.getString(0));
    int range = (end - start) + 1;

    int cursorChoice = rand.nextInt(5);
    int cursor2Choice = rand.nextInt(5);

    switch (randOp)
    {
    case 0:
        randName = rand.nextInt(45);
        name = getRandomName(randName);
        int nullNotNull = rand.nextInt(2);
        switch (nullNotNull)
        {
        case 0:
            field = null;
            break;
        case 1:
            randField = rand.nextInt(24);
            field = getRandomField(randField);
            break;
        }
        testInsert(cursors[cursorChoice], name, field);
        break;
    case 1:
        id = rand.nextInt(range)+start;
        testDelete(cursors[cursorChoice], id);
        break;
    case 2:
        int selection = rand.nextInt(5);
        switch (selection)
        {
        case 0:
            randName = rand.nextInt(45);
            id = rand.nextInt(range)+start;
            name = getRandomName(randName);
            testUpdate(id, name, "");
            break;
        default:
            randName = rand.nextInt(45);
            name = getRandomName(randName);
            randField = rand.nextInt(24);
            field = getRandomField(randField);
            id = rand.nextInt(range)+start;
            testUpdate(id, name, field);
            break;
        }
        break;
    case 3:
        id = rand.nextInt(range)+start;
        testGet(cursors[cursorChoice], id);
        break;
    case 4:
        testGetAll(cursors[cursorChoice]);
        break;
    case 5:
        selection = rand.nextInt(5);
        switch (selection)
        {
        case 0:
            randName = rand.nextInt(45);
            name = getRandomName(randName);
            testOverWrite(rand, name, "");
            break;
        default:
            randName = rand.nextInt(45);
            name = getRandomName(randName);
            randField = rand.nextInt(24);
            field = getRandomField(randField);
            testOverWrite(rand, name, field);
            break;
        }
        break;
    case 6:
        testJoin(cursors[cursorChoice], cursors[cursor2Choice]);
        break;
    case 7:
        testJoin(cursors[cursorChoice], cursors[cursor2Choice]);
        break;
    case 8:
        testJoin(cursors[cursorChoice], cursors[cursor2Choice]);
        break;
    }   
}

 }

这是我收到错误的地方:

java.lang.Error: Could not make new 'Blah' table.
at com.example.sql2.test.SQLSuiteVer2.testJoin(SQLSuiteVer2.java:99)
at com.example.sql2.test.SQLSuiteVer2.randomTest(SQLSuiteVer2.java:410)
at com.example.sql2.test.SQLSuiteVer2.testSuite(SQLSuiteVer2.java:43)
at java.lang.reflect.Method.invokeNative(Native Method)
at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)
at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199)
at android.test.ActivityInstrumentationTestCase2.runTest(ActivityInstrumentationTestCase2.java:192)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:190)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:175)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:555)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1584)

一切正常,直到我添加了三个连接方法,一个覆盖了一个方法。

2 个答案:

答案 0 :(得分:0)

您的问题提到重新打开已关闭对象错误。但是你的logcat显示了java.lang.Error异常。这是哪个错误?

如果使用logcat作为指南。也许这是你第二次运行测试,表'Blah'已经存在?您不能使用相同的名称创建两次相同的表。解决此问题的方法是从'setUp'方法中删除所有表。这样你的测试就从空数据库开始。或者,您可以将测试方法'testJoin'删除表'Blah'(如果已存在),并重新创建它。

答案 1 :(得分:0)

我自己解决了这个问题。我去尝试深入了解(我认为问题无法通过我添加的内容,考虑到代码在添加之前工作正常)并找到了:

public SQLAdapter open() throws SQLException
{
    try
    {
        helper.openDatabase();
        helper.close();
        database = helper.getWritableDatabase();
    } catch (SQLException e) {
        Log.e(TAG, " open >>" + e.toString());
        throw e;
    }
    return this;
}

我认为这是问题的原因(帮助程序是我用来创建/复制和访问数据库的SQLiteOpenHelper的子类)。我删除了helper.close()部分,因为我有一个已经在我的SQLAdapter类中执行此操作的方法,因此稍后当我完成工作时将调用helper.close()方法。