سؤال

I am very new to flex and have no idea what is going on, lol. I want to create a large database from an xml file but while inserting the records in the database the app freezes until everything is done. I have an AS3 file creating the database and the busy indicator in the actual view where press a button to create the database. When I do this the code runs without showing the busy indicator.

I was thinking that maybe the busy indicator should be in the actual AS3 file but I'm not sure how to go about it. Can anyone help point in the right direction? Thank you.

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>

----ADDED HOW IM CREATING MY 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);
        }

    }
هل كانت مفيدة؟

المحلول

AS3 is currently single-threaded (there is ongoing work to make it multi-threaded in an upcoming release). This means that, while your code is processing data and updating the database, no other code will run, including the code that updates the visuals of the busy indicator.

It is a bit difficult to give advice without seeing you db-related code (I assume it is SQLite) but, a way to circumvent this problem, would be to process your database in asynchronous mode.

I don't know how you are processing your inserts but, also, in SQLite, you can speed them up considerably by manually controlling when transactions start and end. Otherwise, it will default to one transaction per insert (which will be very slow and will freeze your display even longer).

نصائح أخرى

As @Eduardo alluded to, make sure you call the openAsynch(...) method for SQLite, and generally during either large set insert's / create's wrap all that up in a begin() / commit() transaction. Otherwise if you execute each sqlstatement, you'll end up processing everything as a single transaction which is noose by which to hang your thread.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top