【问题标题】:ASyncTask on MainActivity block UI LayoutMainActivity 块 UI 布局上的 ASyncTask
【发布时间】:2014-09-17 08:35:56
【问题描述】:

我得到以下代码,我不知道为什么主 ui 阻塞(等待 DoaJsonReader 完成)。是的,我已经阅读了所有其他问题,通常问题是滥用 .get() 方法。但我不会在任何地方使用它。

程序运行良好,但布局未加载,只要执行 DoaJsonReader,它只会显示带有标题的空白活动,并在 ASyncTask 完成后显示布局的一瞥(大约 0.5 秒)。

这里是我的代码:

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;

public class Loading extends Activity {
    private Thread thread;
    DoaData DD;
    @Override
    protected void onCreate(Bundle savedInstanceState) {

        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_loading);
        DD = new DoaData(this);
        Toast.makeText(getApplicationContext(), "Loading app resources ...", Toast.LENGTH_LONG).show();
        DoaJsonReader jr = new DoaJsonReader();
        jr.execute("http://myweb.id/APPS/DOA/?i=index.json");
    }

    private class DoaJsonReader extends AsyncTask<String, Void, String> {
        @Override
        protected String doInBackground(String... urls) {
            String response = "";
            for (String url : urls) {
                DefaultHttpClient client = new DefaultHttpClient();
                HttpGet httpGet = new HttpGet(url);
                try {
                    HttpResponse execute = client.execute(httpGet);
                    InputStream content = execute.getEntity().getContent();

                    BufferedReader buffer = new BufferedReader(
                            new InputStreamReader(content));
                    String s = "";
                    while ((s = buffer.readLine()) != null) {
                        response += s;
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return response;
        }

        @Override
        protected void onPostExecute(String result) {

            ArrayList<String> stringArray = new ArrayList<String>();
            JSONArray jsonArray = null;
            JSONObject jsonObject = null;
            String lastupdate="";
            try {

                //jsonArray = new JSONArray(result);
                jsonObject= new JSONObject(result);
                lastupdate=jsonObject.get("lastupdate").toString();

                jsonArray=new JSONArray(jsonObject.get("index").toString());
            } catch (Exception e) {
                e.printStackTrace();
            }
            DD.truncateIndex();
            for(int i = 0, count = jsonArray.length(); i< count; i++)
            {
                try {
                    jsonObject = jsonArray.getJSONObject(i);
                    DD.insertIndex(jsonObject.getString("title").toString(),jsonObject.getString("file").toString(),jsonObject.getString("tags").toString());
                }
                catch (JSONException e) {
                    e.printStackTrace();
                }finally {
                    DD.insertParam("lastupdate",lastupdate);
                }
            }
            finish();
        }
    }

}

public class DoaData extends SQLiteOpenHelper {
    private static final int DATABASE_VERSION = 1;
    private static final String DATABASE_NAME = "DOA.db";
    public static final String TABLE_DOA = "DOA_INDEX";
    public static final String TABLE_PARAM = "DOA_PARAM";

    public DoaData(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub
        db.execSQL("DROP TABLE IF EXISTS "+TABLE_DOA);
        db.execSQL("DROP TABLE IF EXISTS "+TABLE_PARAM);
        onCreate(db);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE "+TABLE_DOA+" (title TEXT,file TEXT, tags TEXT);");
        db.execSQL("CREATE TABLE "+TABLE_PARAM+" (key TEXT,value TEXT);");
    }
    public void insertIndex(String title, String file, String tags){
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues cv = new ContentValues();
        cv.put("title",title);
        cv.put("file",file);
        cv.put("tags",tags);
        db.insert(TABLE_DOA,null,cv);
        db.close(); // Closing database connection
    }
    public List<DoaIndex> getIndexes() {
        List<DoaIndex> DoaIndexList = new ArrayList<DoaIndex>();
        String selectQuery = "Select * From " + TABLE_DOA +";";
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor = db.rawQuery(selectQuery, null);
        int i = 0;
        if (cursor.moveToFirst()) {
            do {
                DoaIndex idx = new DoaIndex(i, cursor.getString(0), cursor.getString(1), cursor.getString(2));
                // Adding contact to list
                DoaIndexList.add(idx);
            } while (cursor.moveToNext());
            db.close();
        }
        return DoaIndexList;
    }
    public void truncateIndex(){
        SQLiteDatabase db = this.getWritableDatabase();
        db.execSQL("DELETE FROM "+TABLE_DOA+";");
        db.execSQL("VACUUM;");
        db.close();
    }
    public void insertParam(String key, String value){
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues cv = new ContentValues();
        cv.put("key",key);
        cv.put("value",value);
        db.insert(TABLE_PARAM, null, cv);
        db.close();
    }

}

【问题讨论】:

  • 你调试过 onPostExecute() 吗?
  • 是的,我有,它运行正常。你想知道什么?
  • 为什么调用finish();在 onPostExecute() 中?什么是 DoaData?
  • 因为我想在来自网络的数据加载完成后返回到 MainActivity。我从 MainActivity 调用 Loading (Activity),我已经尝试将启动活动更改为 Loading 并调用 MainActivity 之后,但它没有改变任何东西(用户界面仍然被阻止)。 Doa 数据是我的 SQLiteOpenHelper
  • 您能否尝试将您的DD相关代码在JSONArray初始化后放入runOnUiThread()中。

标签: android multithreading android-layout android-activity android-asynctask


【解决方案1】:

要么删除 DoaJsonReader jr = new DoaJsonReader();或者直接做

jr.execute("http://myweb.id/APPS/DOA/?i=index.json");

【讨论】:

  • 对不起,我已经编辑了代码。我要么使用:DoaJsonReader jr = new DoaJsonReader(); jr.execute("http://myweb.id/APPS/DOA/?i=index.json"); 要么 new DoaJsonReader().execute("http://myweb.id/APPS/DOA/?i=index.json"); 它没有效果
【解决方案2】:

试试这个方法,希望能帮助你解决问题。

class DoaJsonReader extends AsyncTask<String, Void, String> {
    @Override
    protected String doInBackground(String... urls) {
        String response = "";
        for (String url : urls) {
            DefaultHttpClient client = new DefaultHttpClient();
            HttpGet httpGet = new HttpGet(url);
            try {
                HttpResponse execute = client.execute(httpGet);
                InputStream content = execute.getEntity().getContent();

                BufferedReader buffer = new BufferedReader(
                        new InputStreamReader(content));
                String s = "";
                while ((s = buffer.readLine()) != null) {
                    response += s;
                }

                JSONArray jsonArray = null;
                JSONObject jsonObject = null;
                String lastupdate="";
                jsonObject= new JSONObject(response);
                lastupdate=jsonObject.get("lastupdate").toString();
                jsonArray=new JSONArray(jsonObject.get("index").toString());
                DD.truncateIndex();
                for(int i = 0, count = jsonArray.length(); i< count; i++)
                {
                    try {
                        jsonObject = jsonArray.getJSONObject(i);
                        DD.insertIndex(jsonObject.getString("title").toString(),jsonObject.getString("file").toString(),jsonObject.getString("tags").toString());
                    }
                    catch (JSONException e) {
                        e.printStackTrace();
                    }finally {
                        DD.insertParam("lastupdate",lastupdate);
                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return response;
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        finish();
    }
}

【讨论】:

  • 我试过了,它给了我以下错误Error:(85, 44) error: local variable jsonArray is accessed from within inner class; needs to be declared final... 我已经将所有变量移动到主类并消除了所有错误,但它并没有解决问题。我能知道为什么我们在 ASyncTask 中运行另一个线程吗?谢谢顺便说一句
  • 好的,然后像上面的 onCreate() 一样在类成员级别移动 JSONArray jsonArray 变量。
  • 好的,我已经将所有变量移到主类public class Loading extends Activity { private Thread thread; DoaData DD; JSONArray jsonArray = null; JSONObject jsonObject = null; String lastupdate=""; @Override protected void onCreate(Bundle savedInstanceState) { ...它对程序没有影响。
【解决方案3】:

已解决:我最终使用不同的名称重新创建所有活动和布局,然后将所有插入到数据库代码移动到 doInBackground 方法。 谢谢大家。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-05
    相关资源
    最近更新 更多