Android SQLite中的Recyclerview第一次显示空页面

Android SQLite中的Recyclerview第一次显示空页面,android,sqlite,android-asynctask,Android,Sqlite,Android Asynctask,我正在尝试从异步任务填充recyclerview。在异步任务中,通过API调用获取数据并将其推送到SQLite表,然后从SQLite表填充列表。第一次加载时列表无法显示。但当我关闭应用程序并重新打开应用程序时,列表将填充。这是一个需要适当解决的一般性问题,还是我遗漏了其他问题 public class KingsActivity extends AppCompatActivity { RecyclerView mRecyclerView; RecyclerView.Adapter

我正在尝试从异步任务填充
recyclerview
。在异步任务中,通过API调用获取数据并将其推送到SQLite表,然后从SQLite表填充列表。第一次加载时列表无法显示。但当我关闭应用程序并重新打开应用程序时,列表将填充。这是一个需要适当解决的一般性问题,还是我遗漏了其他问题

public class KingsActivity extends AppCompatActivity {
    RecyclerView mRecyclerView;
    RecyclerView.Adapter mAdapter;
    RecyclerView.LayoutManager mLayoutManager;
    List<King> kingList=new ArrayList<King>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.d("method_track","onCreate");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //To avoid the load on the main thread
        new DownloadDataAsync().execute(this);


    }

    public class DownloadDataAsync extends AsyncTask<Context, Integer, Context> {

        @Override
        protected Context doInBackground(Context... ctx) {
            downloadData(ctx[0]);
            return ctx[0];
        }

        @Override
        protected void onProgressUpdate(Integer... progress) {
        }

        @Override
        protected void onPostExecute(Context result) {

            Log.d("method_track","PostExecute");
            Cursor kingsRows=DatabaseHelper.getInstance(result.getApplicationContext()).getData(DatabaseHelper.TABLE_WESTEROS_KINGS);
            kingsRows.moveToFirst();
            while(kingsRows.moveToNext()){
                String kingName=kingsRows.getString(kingsRows.getColumnIndex(DatabaseHelper.KEY_WESTEROS_KINGS_NAME));
                int battleCount=kingsRows.getInt(kingsRows.getColumnIndex(DatabaseHelper.KEY_WESTEROS_KINGS_BATTLE_COUNT));
                int rating=kingsRows.getInt(kingsRows.getColumnIndex(DatabaseHelper.KEY_WESTEROS_KINGS_RATING));
                kingList.add(new King(kingName,rating,battleCount));

            }
            kingsRows.close();


            mRecyclerView = (RecyclerView)findViewById(R.id.my_recycler_view);

            mLayoutManager = new LinearLayoutManager(result);
            mRecyclerView.setLayoutManager(mLayoutManager);
            mAdapter = new KingsAdapterRC(kingList,result);
            mRecyclerView.setAdapter(mAdapter);
            mAdapter.notifyDataSetChanged();
        }

        public void downloadData(final Context ctx){
            // Get a RequestQueue
            RequestQueue queue = HttpRequestHandler.getInstance(ctx.getApplicationContext()).
                    getRequestQueue();

            String url ="http://starlord.hackerearth.com/gotjson";
            // Request a string response from the provided URL.
            StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
                    new Response.Listener<String>() {
                        @Override
                        public void onResponse(String response) {
                            // Display the first 500 characters of the response string.
                            //Log.d("result_check",response.substring(0,500));

                            loadToDb(response,ctx);
                            populateList(ctx);
                            calculateRating(ctx);
                            logRatings(ctx);


                            //mTextView.setText("Response is: "+ response.substring(0,500));
                        }
                    }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Log.d("result_check","Error");
                    //mTextView.setText("That didn't work!");
                }
            });

            // Add a request to RequestQueue.
            HttpRequestHandler.getInstance(ctx).addToRequestQueue(stringRequest);
        }
        protected void loadToDb(String jsonResponse,Context ctx){
            DatabaseHelper.getInstance(ctx.getApplicationContext()).truncate(DatabaseHelper.TABLE_WESTEROS_DATA);
            try {
                JSONArray jsonArray = new JSONArray(jsonResponse);
                for(int i=0;i<jsonArray.length();i++){
                    JSONObject jsonObj = (JSONObject)jsonArray.get(i);
                    Iterator<String> iter = jsonObj.keys();
                    HashMap<String,String> fieldVales=new HashMap<String, String>();
                    while (iter.hasNext()) {
                        String key = iter.next();
                        try {
                            Object value = jsonObj.get(key);
                            fieldVales.put(key,value.toString());

                        } catch (JSONException e) {
                            // Something went wrong!
                            Log.e("loadTodb",e.toString());
                        }
                    }
                    DatabaseHelper.getInstance(ctx.getApplicationContext()).insert(DatabaseHelper.TABLE_WESTEROS_DATA,fieldVales);
                }

            } catch (Throwable t) {
                //Log.e("My App", "Could not parse malformed JSON: \"" + json + "\"");
            }
        }
        protected void populateList(Context ctx){
            List<King> kingList=new ArrayList<King>();
            String[] kings;
            int kingsCount=0;
            String sql="SELECT DISTINCT "+DatabaseHelper.KEY_WESTEROS_ATTACKER_KING+ " FROM "+ DatabaseHelper.TABLE_WESTEROS_DATA
                    +" WHERE "+ DatabaseHelper.KEY_WESTEROS_ATTACKER_KING +" <> ''";
            Cursor rows=DatabaseHelper.getInstance(ctx.getApplicationContext()).getReadableDatabase().rawQuery(sql, null);
            kingsCount+=rows.getCount();



            String sql2="SELECT DISTINCT "+DatabaseHelper.KEY_WESTEROS_DEFENDER_KING + " FROM "+ DatabaseHelper.TABLE_WESTEROS_DATA
                    + " WHERE "+ DatabaseHelper.KEY_WESTEROS_DEFENDER_KING + " NOT IN ( "+sql+ " ) AND "
                    + DatabaseHelper.KEY_WESTEROS_DEFENDER_KING +" <> ''";

            Cursor rows2=DatabaseHelper.getInstance(ctx.getApplicationContext()).getReadableDatabase().rawQuery(sql2, null);
            kingsCount+=rows2.getCount();

            kings=new String[kingsCount];
            int i=0;

            if (rows.moveToFirst()) {
                while (!rows.isAfterLast()) {
                    //your code to implement
                    kings[i]=rows.getString(rows.getColumnIndex(DatabaseHelper.KEY_WESTEROS_ATTACKER_KING));
                    i++;
                    rows.moveToNext();
                }
            }
            rows.close();

            if (rows2.moveToFirst()) {
                while (!rows2.isAfterLast()) {
                    //your code to implement
                    kings[i]=rows2.getString(rows2.getColumnIndex(DatabaseHelper.KEY_WESTEROS_DEFENDER_KING));
                    i++;
                    rows2.moveToNext();
                }
            }
            rows2.close();


            DatabaseHelper.getInstance(ctx.getApplicationContext()).truncate(DatabaseHelper.TABLE_WESTEROS_KINGS);
            for(i=0;i<kingsCount;i++){
                HashMap<String,String> fieldValues=new HashMap<String, String>();
                fieldValues.put(DatabaseHelper.KEY_WESTEROS_KINGS_NAME,kings[i]);
                fieldValues.put(DatabaseHelper.KEY_WESTEROS_KINGS_RATING,"400");
                fieldValues.put(DatabaseHelper.KEY_WESTEROS_KINGS_BATTLE_COUNT,"0");
                DatabaseHelper.getInstance(ctx.getApplicationContext()).insert(DatabaseHelper.TABLE_WESTEROS_KINGS,fieldValues);
            }
        }


        protected void calculateRating(Context ctx){
            Cursor battles_cur=DatabaseHelper.getInstance(ctx.getApplicationContext()).getData(DatabaseHelper.TABLE_WESTEROS_DATA);

            if(battles_cur.moveToFirst()){
                while(!battles_cur.isAfterLast()){
                    String attackingKing=battles_cur.getString(battles_cur.getColumnIndex(DatabaseHelper.KEY_WESTEROS_ATTACKER_KING));
                    String defendingKing=battles_cur.getString(battles_cur.getColumnIndex(DatabaseHelper.KEY_WESTEROS_DEFENDER_KING));


                    if(!attackingKing.equals("") && !defendingKing.equals("")){

                        HashMap<String,String> whereConDfk=new HashMap<String,String>();
                        whereConDfk.put(DatabaseHelper.KEY_WESTEROS_KINGS_NAME,defendingKing);
                        Cursor cursor1=DatabaseHelper.getInstance(ctx.getApplicationContext()).getData(DatabaseHelper.TABLE_WESTEROS_KINGS,whereConDfk);
                        double defKing_rating;
                        double defKing_battleCount;
                        if(cursor1.moveToFirst()){

                            defKing_rating=cursor1.getDouble(cursor1.getColumnIndex(DatabaseHelper.KEY_WESTEROS_KINGS_RATING));
                            defKing_battleCount=cursor1.getDouble(cursor1.getColumnIndex(DatabaseHelper.KEY_WESTEROS_KINGS_BATTLE_COUNT));
                            cursor1.close();

                            HashMap<String,String> whereConAtk=new HashMap<String,String>();
                            whereConAtk.put(DatabaseHelper.KEY_WESTEROS_KINGS_NAME,attackingKing);
                            Cursor cursor2=DatabaseHelper.getInstance(ctx.getApplicationContext()).getData(DatabaseHelper.TABLE_WESTEROS_KINGS,whereConAtk);
                            Double atkKing_rating;
                            Double atkKing_battleCount;
                            if(cursor2.moveToFirst()){

                                atkKing_rating=cursor2.getDouble(cursor2.getColumnIndex(DatabaseHelper.KEY_WESTEROS_KINGS_RATING));
                                atkKing_battleCount=cursor2.getDouble(cursor2.getColumnIndex(DatabaseHelper.KEY_WESTEROS_KINGS_BATTLE_COUNT));
                                cursor2.close();
                                atkKing_battleCount++;
                                defKing_battleCount++;

                                Double defKing_rating_tr=Math.pow(10,(defKing_rating/400));
                                Double atkKing_rating_tr=Math.pow(10,(atkKing_rating/400));

                                Double defKing_rating_ex=defKing_rating_tr/(defKing_rating_tr+atkKing_rating_tr);
                                Double atkKing_rating_ex=atkKing_rating_tr/(defKing_rating_tr+atkKing_rating_tr);

                                String attackerStatus=battles_cur.getString(battles_cur.getColumnIndex(DatabaseHelper.KEY_WESTEROS_ATTACKER_OUTCOME));

                                Double atkKing_rating_new=atkKing_rating;
                                Double defKing_rating_new=defKing_rating;
                                if(attackerStatus.equals("win")){
                                    atkKing_rating_new=atkKing_rating+(32*(1-atkKing_rating_ex));
                                    defKing_rating_new=defKing_rating+(32*(0-defKing_rating_ex));
                                }else if(attackerStatus.equals("loss")){
                                    atkKing_rating_new=atkKing_rating+(32*(0-atkKing_rating_ex));
                                    defKing_rating_new=defKing_rating+(32*(1-defKing_rating_ex));
                                }else if(attackerStatus.equals("draw")){
                                    atkKing_rating_new=atkKing_rating+(32*(0.5-atkKing_rating_ex));
                                    defKing_rating_new=defKing_rating+(32*(0.5-defKing_rating_ex));
                                }
                                String update_atkKing_ratingQuery="UPDATE "+ DatabaseHelper.TABLE_WESTEROS_KINGS + " SET "
                                        + DatabaseHelper.KEY_WESTEROS_KINGS_RATING+" = "+atkKing_rating_new+", "
                                        + DatabaseHelper.KEY_WESTEROS_KINGS_BATTLE_COUNT+" = "+atkKing_battleCount
                                        + " WHERE "+ DatabaseHelper.KEY_WESTEROS_KINGS_NAME +" =\""+attackingKing+"\"";

                                String update_defKing_ratingQuery="UPDATE "+ DatabaseHelper.TABLE_WESTEROS_KINGS + " SET "
                                        + DatabaseHelper.KEY_WESTEROS_KINGS_RATING+" = "+defKing_rating_new+", "
                                        + DatabaseHelper.KEY_WESTEROS_KINGS_BATTLE_COUNT+" = "+defKing_battleCount
                                        + " WHERE "+ DatabaseHelper.KEY_WESTEROS_KINGS_NAME +" =\""+defendingKing+"\"";

                                DatabaseHelper.getInstance(ctx.getApplicationContext()).getWritableDatabase().execSQL(update_atkKing_ratingQuery);
                                DatabaseHelper.getInstance(ctx.getApplicationContext()).getWritableDatabase().execSQL(update_defKing_ratingQuery);

                            }

                        }
                    }
                    battles_cur.moveToNext();
                }
            }

        }
        protected void logRatings(Context ctx){
            Log.d("method_track","logratings");
            Cursor kings_cur=DatabaseHelper.getInstance(ctx.getApplicationContext()).getData(DatabaseHelper.TABLE_WESTEROS_KINGS);
            try {
                while (kings_cur.moveToNext()) {

                    String name=kings_cur.getString(kings_cur.getColumnIndex(DatabaseHelper.KEY_WESTEROS_KINGS_NAME));
                    String rating=kings_cur.getString(kings_cur.getColumnIndex(DatabaseHelper.KEY_WESTEROS_KINGS_RATING));
                    String battleCount=kings_cur.getString(kings_cur.getColumnIndex(DatabaseHelper.KEY_WESTEROS_KINGS_BATTLE_COUNT));
                    //Log.d("method_track", "logratings");
                    Log.d("rating_inspect",name+" - "+rating+" - "+battleCount);

                }
            }finally {
                kings_cur.close();
            }

        }
    }



}
公共类KingsActivity扩展了AppCompative活动{
回收视图mRecyclerView;
RecyclerView.适配器制造商;
RecyclerView.LayoutManager mllayoutmanager;
List kingList=new ArrayList();
@凌驾
创建时受保护的void(Bundle savedInstanceState){
Log.d(“方法跟踪”,“创建”);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//以避免主螺纹上的负载
新建DownloadDataAsync().execute(此);
}
公共类DownloadDataAsync扩展AsyncTask{
@凌驾
受保护的上下文doInBackground(上下文…ctx){
下载数据(ctx[0]);
返回ctx[0];
}
@凌驾
受保护的void onProgressUpdate(整数…进度){
}
@凌驾
受保护的void onPostExecute(上下文结果){
Log.d(“方法跟踪”、“后执行”);
游标kingsRows=DatabaseHelper.getInstance(result.getApplicationContext()).getData(DatabaseHelper.TABLE\u WESTEROS\u KINGS);
kingsRows.moveToFirst();
while(kingsRows.moveToNext()){
String kingName=kingsRows.getString(kingsRows.getColumnIndex(DatabaseHelper.KEY_WESTEROS_KINGS_NAME));
int battleCount=kingsRows.getInt(kingsRows.getColumnIndex(DatabaseHelper.KEY\u WESTEROS\u KINGS\u BATTLE\u COUNT));
int rating=kingsRows.getInt(kingsRows.getColumnIndex(DatabaseHelper.KEY\u WESTEROS\u KINGS\u rating));
国王列表。添加(新国王(国王名称、等级、战斗计数));
}
kingsRows.close();
mRecyclerView=(RecyclerView)findViewById(R.id.my\u recycler\u视图);
mLayoutManager=新的LinearLayoutManager(结果);
mRecyclerView.setLayoutManager(mllayoutmanager);
mAdapter=新的Kingsadapterc(KingsList,result);
mRecyclerView.setAdapter(mAdapter);
mAdapter.notifyDataSetChanged();
}
公共无效下载数据(最终上下文ctx){
//获取请求队列
RequestQueue queue=HttpRequestHandler.getInstance(ctx.getApplicationContext())。
getRequestQueue();
字符串url=”http://starlord.hackerearth.com/gotjson";
//从提供的URL请求字符串响应。
StringRequest StringRequest=新的StringRequest(Request.Method.GET,url,
新的Response.Listener(){
@凌驾
公共void onResponse(字符串响应){
//显示响应字符串的前500个字符。
//Log.d(“结果检查”,响应子字符串(0500));
loadToDb(响应,ctx);
大众主义者(ctx);
计算(ctx);
对数额定值(ctx);
//mTextView.setText(“响应为:”+Response.substring(0500));
}
},new Response.ErrorListener(){
@凌驾
公共无效onErrorResponse(截击错误){
Log.d(“结果检查”、“错误”);
//setText(“那没用!”);
}
});
//将请求添加到RequestQueue。
HttpRequestHandler.getInstance(ctx).addToRequestQueue(stringRequest);
}
受保护的void loadToDb(字符串jsonResponse,上下文ctx){
DatabaseHelper.getInstance(ctx.getApplicationContext()).truncate(DatabaseHelper.TABLE\u WESTEROS\u DATA);
试一试{
JSONArray JSONArray=新的JSONArray(jsonResponse);
对于(int i=0;i这里:

下载数据方法引起的问题

downloadData
方法中,使用
StringRequest
从服务器获取数据。
StringRequest
处理工作线程上的所有请求,并使用
Response.Listener返回结果

doInBackground
也完成了工作线程上的所有工作。因此
doInBackground
方法的工作线程只执行
downloadData
方法,而不等待从
StringRequest
获取响应


使用
StringRequest
时不需要使用额外的线程。只需删除
AsyncTask
并仅使用
StringRequest
即可使其正常工作。

您不应该从
doInBackground
调用凌空
StringRequest
,因为
异步任务
立即触发
后执行
方法d,您的列表将为空,因此不会显示任何数据。只需使用
字符串请求
,并在收到响应后将其保存到“数据库”中并从那里获取(您可以直接或使用异步任务从
数据库
保存和获取数据)


不只是使用
StringRequest
而不使用任何
异步任务
并对其进行测试。

调试您的应用程序。。它将第一次向您显示实际发生的情况。…尝试删除mAdapter.notifyDataSetChanged();不要在onPostExecute内初始化回收器视图在调用异步任务之前执行此操作,并在从异步任务i中获取列表后调用notifyDataSetChange更新适配器列表,在onPostExecute内当我使用而不使用异步任务时,我收到以下消息
i/Choreographer:跳过68帧!应用程序可能做了太多工作在它的主线程上。
和thi
downloadData(ctx[0]);