空白/黑色屏幕上的应用程序启动时,由于数据下载? [英] Blank/black screen on app startup due data downloading?

查看:140
本文介绍了空白/黑色屏幕上的应用程序启动时,由于数据下载?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

该应用程序我开发下载远程地址在每次启动一个JSON文件,然后解析JSON对象和数据复制到sqlite的手机上。
这种操作是其应用程序挂起几秒钟就显示空白屏幕每一次启动的原因(或某个空白,然后黑屏),其实如果我试图禁用$ C $,这部分c中的应用程序启动迅速,无挂。
所以,我怎么会做的更好?

下面是文件下载,分析和编写本地的SQLite数据库相关code(DataHandler的类):

 公共类的DataHandler {    公众的DataHandler(){
    }    公众诠释storeData(数据库DB,INT NUM)抛出JSONException {        HttpClient的客户端=新DefaultHttpClient();
        HTTPGET请求=新HTTPGET(http://www.example.com/data.json);
        request.addHeader(缓存控制,无缓存);
        长ID = -1;        尝试{
            HTT presponse响应= client.execute(请求);
            HttpEntity实体= response.getEntity();
            InputStreamReader的在=新的InputStreamReader(entity.getContent());
            读者的BufferedReader =新的BufferedReader(中);
            StringBuilder的StringBuilder的=新的StringBuilder();
            串线=;            而((行= reader.readLine())!= NULL){
                stringBuilder.append(线);
            }            JSONArray jsonArray =新JSONArray(stringBuilder.toString());
            SQLiteDatabase dbWrite = db.getWritableDatabase();
            ContentValues​​值=新ContentValues​​();            如果(jsonArray.length()== NUM​​和放大器;&安培;!NUM = 0)
                返回NUM;            SQLiteDatabase dbread = db.getReadableDatabase();
            dbread.delete(mytable的,1,空);
            的for(int i = 0; I< jsonArray.length();我++){
                JSONObject的jObj =(JSONObject的)jsonArray.getJSONObject(I)                values​​.put(_ ID,jObj.optString(ID)的toString());
                values​​.put(城市,jObj.optString(城市)的toString());
                values​​.put(国家,jObj.optString(国家)的toString());
                values​​.put(地址,jObj.optString(地址)的toString());
                values​​.put(称号,jObj.optString(题)的toString());
                values​​.put(LON,jObj.optString(LON)的toString());
                values​​.put(电子邮件,jObj.optString(电子邮件)的toString());
                values​​.put(手机,jObj.optString(手机)的toString());
                values​​.put(网,jObj.optString(网)的toString());
                values​​.put(纬度,jObj.optString(纬度)的toString());
                values​​.put(DESC,jObj.optString(DESC)的toString());
                values​​.put(图标,jObj.optString(图标)的toString());
                values​​.put(类别,jObj.optString(类别)的toString());                ID = dbWrite.insert(商人,空,价值);
            }
            NUM = jsonArray.length();        }赶上(ClientProtocolException E){
            e.printStackTrace();
        }赶上(IOException异常五){
            e.printStackTrace();
        }        如果(ID大于0)
            返回NUM;
        其他
            返回-1;
    }
}


解决方案

她进入你的异步任务类

 类AsyncClass扩展的AsyncTask<弦乐,太虚,字符串>
{
    INT结果;
    上下文语境;
    ProgressDialog吧;
    AsynclassListener<串GT;侦听器;
    公共AsyncClass(上下文的背景下,AsynclassListener听众){//添加更多的参数,作为方法的身体有(即数据库DB,INT NUM)。不要忘了初始化。
        this.context =背景;
        this.listener =侦听器;
        巴=新ProgressDialog(背景);
        bar.setIndeterminate(假);
    //在这里做你的进度我刚才给上面PB有更多的参数来设置一个简单的例子。
    }    保护字符串doInBackground(字符串参数...){    尝试{
      结果= storeData(); //调用你的方法在这里    }赶上(例外五){
        //做一些事情的时候崩溃    }
    返回+结果;}    @覆盖
    在preExecute保护无效(){
        // TODO自动生成方法存根
        super.on preExecute();
        bar.show(); //你的数据获取和分析会在你这个进度条将是可见的时间。
    }    @覆盖
    保护无效onPostExecute(字符串结果){
        // TODO自动生成方法存根
        super.onPostExecute(结果);
        bar.dismiss(); //只要工作完成的这个方法被调用。
         listener.onTaskComplete(+结果);
         / **
          *在你的情况,一旦你收到结果以后可以强制转换回整数。
          *这个监听器将发布结果到您的主要活动。
          * /    }}


下面是你的接口

 公共接口AsynclassListener< T> {    公共无效onTaskComplete(T结果);}


现在让你的活动(飞溅类)实现接口
这将实现该方法为:

  @覆盖
    公共无效onTaskComplete(字符串结果){
        //这里的asynclass会后的结果作为任何你想要的1或-1。
//之后,你可能会即切换到下一个活动或者让你的下一个部分进行。
    }


编辑:我忘了提及如何将其称为:

 新AsyncClass(getApplicationContext(),这一点).execute(); //在这里你必须输入数据库,这将需要运行的方法等参数值。相应地更改它。


正如你可以在这里看到你的方法,你是取净和分析也是数据:
再有,可以在其中调用网络卡尔在一个单独的线程和后来的分析可以进一步在UIthread被做了第二种方法。

另外阅读有关​​异步任务类,以了解参数和类的工作。

The app i'm developing downloads a JSON file from remote address at every startup and then it parses the JSON Object and copies data to SQLite on the phone. This operation is the cause for which the app hangs for some seconds on every startup showing blank screen (or sometime blank and then black screen), in fact if i tried to disable this part of code the app starts quickly, with no hang. So, how could i do it better?

Here is the code (DataHandler class) related to file download, parsing and writing to local SQLite db:

public class DataHandler {

    public DataHandler() {
    }

    public int storeData(Database db, int num) throws JSONException {

        HttpClient client = new DefaultHttpClient();
        HttpGet request = new HttpGet("http://www.example.com/data.json");
        request.addHeader("Cache-Control", "no-cache");
        long id = -1;

        try {
            HttpResponse response = client.execute(request);
            HttpEntity entity = response.getEntity();
            InputStreamReader in = new InputStreamReader(entity.getContent());
            BufferedReader reader = new BufferedReader(in);
            StringBuilder stringBuilder = new StringBuilder();
            String line = "";

            while ((line=reader.readLine()) != null) {
                stringBuilder.append(line);
            }

            JSONArray jsonArray = new JSONArray(stringBuilder.toString());
            SQLiteDatabase dbWrite = db.getWritableDatabase();
            ContentValues values = new ContentValues();

            if (jsonArray.length() == num && num != 0)
                return num;

            SQLiteDatabase dbread = db.getReadableDatabase();
            dbread.delete("mytable", "1", null);
            for (int i = 0; i < jsonArray.length(); i++) {
                JSONObject jObj = (JSONObject) jsonArray.getJSONObject(i);

                values.put("_id", jObj.optString("id").toString());
                values.put("city", jObj.optString("city").toString());
                values.put("country",jObj.optString("country").toString());
                values.put("addr", jObj.optString("addr").toString());
                values.put("title", jObj.optString("title").toString());
                values.put("lon", jObj.optString("lon").toString());
                values.put("email", jObj.optString("email").toString());
                values.put("phone", jObj.optString("phone").toString());
                values.put("web", jObj.optString("web").toString());
                values.put("lat", jObj.optString("lat").toString());
                values.put("desc", jObj.optString("desc").toString());
                values.put("icon", jObj.optString("icon").toString());
                values.put("category", jObj.optString("category").toString());

                id = dbWrite.insert("merchants", null, values);
            }
            num = jsonArray.length();

        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        if (id > 0)
            return num;
        else
            return -1;
    }   
}

解决方案

Her goes your Async Task Class

class AsyncClass extends AsyncTask<String,Void,String>
{
    int result;
    Context context;
    ProgressDialog bar;
    AsynclassListener<String> listener;
    public AsyncClass(Context context, AsynclassListener listener) {//add more parameter as your method body has (i.e Database db, int num) . Don't forget to initialize them.
        this.context=context;
        this.listener=listener;
        bar = new ProgressDialog(context);
        bar.setIndeterminate(false);
    //make your progressBar here I have just given a simple example for above PB there are more parameters to set.
    }

    protected String doInBackground(String... Param){

    try{
      result = storeData();//call your method here

    }catch(Exception e){
        // Do something when crash

    }
    return ""+result;



}

    @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub
        super.onPreExecute();
        bar.show();// By the time your data fetching and parsing will go on you this progress bar will be visible. 
    }

    @Override
    protected void onPostExecute(String result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
        bar.dismiss();//As soon as the work is complete the this method is called. 
         listener.onTaskComplete(""+result);
         /**
          * In your case you can later typecast back in integer once you recieve the result. 
          *  this listener will post the result to your main activity. 
          */

    }

}


Here is your Interface

public interface AsynclassListener<T>{

    public void onTaskComplete(T result);

}


Now Let your Activity (Splash Class) implement the interface This will implement the method as :

 @Override
    public void onTaskComplete(String result) {
        // here the asynclass will post the result as 1 or -1 whatever you want. 
//After that you may proceed with your next part i.e switching to next activity or so.


    }


Edit: I forgot to mention about how this will be called :

 new AsyncClass(getApplicationContext(), this).execute("");// here you have to enter the database and other parameter values that will be required to run the method. Change it accordingly.


As you can see here in your method you are fetching the data from net and parsing also : There is again a second approach in which you can call the network cal in a separate thread and later the parsing can be done further on UIthread.

Also read about the Async Task Class so as to know about the arguments and the working of class.

这篇关于空白/黑色屏幕上的应用程序启动时,由于数据下载?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆