0

私はフレックスに非常に慣れていないので、何が起こっているのかわかりません(笑)。xml ファイルから大規模なデータベースを作成したいのですが、データベースにレコードを挿入している間、すべてが完了するまでアプリがフリーズします。データベースを作成するAS3ファイルと、ボタンを押してデータベースを作成する実際のビューにビジーインジケーターがあります。これを行うと、コードはビジー インジケーターを表示せずに実行されます。

ビジー インジケータは実際の AS3 ファイルにあるはずだと考えていましたが、どうすればよいかわかりません。誰かが正しい方向を指すのを助けることができますか? ありがとうございました。

enter code here
<fx:Script>
<![CDATA[
import skins.BusyPopUpSkin;
import spark.components.SkinnablePopUpContainer;
private var mPopUp:SkinnablePopUpContainer;
import model.DBcreateDAO;


protected function button1_clickHandler(event:MouseEvent):void
{
    // if busy, return
    if (mPopUp)
        return;

    createPopUp();
    startOperation();
}

private function createPopUp():void
{
    // create the SkinnablePopUpContainer
    mPopUp = new SkinnablePopUpContainer();
    // set the styles
    mPopUp.setStyle("skinClass", BusyPopUpSkin);
    mPopUp.setStyle("backgroundColor", 0x000000);
    mPopUp.setStyle("backgroundAlpha", 0.3);

    layoutPopUp();

    // call PopUpManger to open and add
    mPopUp.open(this);

    positionPopUp();
}

private function layoutPopUp():void
{
    // match the popups width, height to the View
    mPopUp.width = width;
    mPopUp.height = height;
}

private function positionPopUp():void
{
    // use the View x, y coords
    var point:Point = new Point(x, y);
    // convert the View x,y to global so this can be laid out in nested Views
    point = parent.localToGlobal(point);
    // set the popup's global x,y coords
    mPopUp.x = point.x;
    mPopUp.y = point.y;
}

private function startOperation():void
{
    trace("The busy indicator should be running while the database is being created.");

    load(); //function for the actionscript file to make database 
}

private function endOperation():void
{
    mPopUp.close();
    mPopUp = null;
}

private function load():void {
            data = srv.create(); //where my function is to create my database in DBcreateDAO.as

    }


    ]]>
</fx:Script>

----私のDBの作成方法を追加----

enter code hereprivate var _sqlConnection:SQLConnection;

    public function get sqlConnection():SQLConnection
    {
        if (_sqlConnection)
            return _sqlConnection;
        openDatabase(File.documentsDirectory.resolvePath("SongListA.db"));
        return _sqlConnection;

    }

    public function loadDB():Song {
            var sql:String = "SELECT id, number, title, artist, item, product FROM song";
        var stmt:SQLStatement = new SQLStatement();
        stmt.sqlConnection = sqlConnection;
        stmt.text = sql;
        stmt.execute();
        var result:Array = stmt.getResult().data;
        if (result && result.length == 1)
            return processRow(result[0]);
        else
            return null;
    }


    public function create(song:Song):void
    {   
        trace(song.title);      
        var sql:String = 
            "INSERT INTO song (id, number, title, artist, item, product) " +
            "VALUES (?,?,?,?,?,?)";
        var stmt:SQLStatement = new SQLStatement();
        stmt.sqlConnection = sqlConnection;
        stmt.text = sql;
        stmt.parameters[0] = song.id;
        stmt.parameters[1] = song.number;
        stmt.parameters[2] = song.title;
        stmt.parameters[3] = song.artist;
        stmt.parameters[4] = song.item;
        stmt.parameters[5] = song.product;
        stmt.execute();
        song.loaded = true;
    }

    protected function processRow(o:Object):Song
    {

        var song:Song = new Song();
        song.id = o.id;
        song.number = o.number == null ? "" : o.number;
        song.title = o.title == null ? "" : o.title;
        song.artist = o.artist == null ? "" : o.artist;
        song.item = o.item == null ? "" : o.item;
        song.product = o.product == null ? "" : o.product;

        song.loaded = true;
        return song;
    }

    public function openDatabase(file:File):void
    {
        var newDB:Boolean = true;
        if (file.exists)
            newDB = false;

        _sqlConnection = new SQLConnection();
        _sqlConnection.open(file);

        if (newDB)
        {
            startOperation();
            createDatabase();
            populateDatabase();

        }
    }

    protected function createDatabase():void
    {
        trace("Creating the database");
        var sql:String = 
            "CREATE TABLE IF NOT EXISTS song ( "+
            "id INTEGER PRIMARY KEY AUTOINCREMENT, " +
            "number TEXT, " +
            "title VTEXT, " +
            "artist TEXT, " +
            "item TEXT, " + 
            "product TEXT) ";
        var stmt:SQLStatement = new SQLStatement();
        stmt.sqlConnection = sqlConnection;
        stmt.text = sql;
        stmt.execute();         
    }

    protected function populateDatabase(event:Event):void
    {
        this.addElement(busyIndicator);
        var file:File = File.applicationDirectory.resolvePath("SongListFile.xml");
        var stream:FileStream = new FileStream();
        stream.open(file, FileMode.READ);
        var xml:XML = XML(stream.readUTFBytes(stream.bytesAvailable));

        stream.close();
        for each (var emp:XML in xml.song)
        {
            var song:Song = new Song();
            song.id = emp.id;
            song.number = emp.number;
            song.title = emp.title;
            song.artist = emp.artist;
            song.item = emp.item;
            song.product = emp.product;
            create(song);
        }

    }
4

2 に答える 2

0

AS3 は現在シングルスレッドです (今後のリリースでマルチスレッド化する作業が進行中です)。これは、コードがデータを処理してデータベースを更新している間、ビジー インジケーターのビジュアルを更新するコードを含め、他のコードは実行されないことを意味します。

データベース関連のコード (SQLite だと思います) を見ずにアドバイスをするのは少し難しいですが、この問題を回避する方法は、データベースを非同期モードで処理することです。

挿入をどのように処理しているかはわかりませんが、SQLite では、トランザクションの開始と終了のタイミングを手動で制御することで、挿入を大幅に高速化できます。そうしないと、デフォルトで挿入ごとに 1 つのトランザクションになります (非常に遅くなり、表示がさらに長くフリーズします)。

于 2012-04-23T20:33:34.540 に答える
0

@Eduardoがほのめかしたように、SQLiteのopenAsynch(...)メソッドを呼び出すようにしてください。通常、大きなセットの挿入/作成中に、すべてをbegin()/ commit()トランザクションにラップします。そうしないと、各 sqlstatement を実行すると、スレッドをハングアップさせる縄である単一のトランザクションとしてすべてを処理することになります。

于 2012-04-24T03:10:26.930 に答える