草庐IT

android - 设置异步任务以将 Json 加载到 ListView 中

coder 2023-12-07 原文

我从服务器上的 PHP 脚本中获取 json 对象,然后使用延迟加载图像将其解析为 ListView 。问题是 json 加载速度相对较快,或者会挂起一两秒钟,具体取决于服务器上的响应,这可能会令人沮丧。当我第一次打开应用程序时,挂起特别烦人,因为它会卡在黑屏上,直到加载对象,然后当我更新应用程序中的列表时,它具有相同但至少已加载 View 。这是我获取 json 的代码:

public void getJson(String selection, String url) {
    JSONObject json = null;
    String formatedcat = selection.toLowerCase();
    ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
    json = JSONfunctions
            .getJSONfromURL(url);
    try {
        //the array title that you parse
        JSONArray category = json.getJSONArray(formatedcat);
        for (int i = 0; i < category.length(); i++) {               
            HashMap<String, String> map = new HashMap<String, String>();
            JSONObject c = category.getJSONObject(i);
            map.put("id", String.valueOf(i));
            map.put("name",
                    c.getString("title"));
            //map.put("text",c.getString("title"));
            map.put("ts",c.getString("run_date") );
            map.put("image","http:"+c.getString("url"));
            mylist.add(map);
        }
    } catch (JSONException e) {

    }
    ListAdapter adapter = new JsonAdapter(this, mylist, R.layout.list,
            new String[] { "name", "text", "ts"}, new int[] { R.id.item_title,
                    R.id.item_subtitle, R.id.timestamp});
    setListAdapter(adapter);        
}

适配器代码:

public class JsonAdapter extends SimpleAdapter {

    public ImageManager imageManager;
    public ListActivity context;
    public ArrayList<HashMap<String,String>> list;
    public String[] fieldNames;
    public int[] fieldTargetIds;

    public JsonAdapter(ListActivity c, 
            ArrayList<HashMap<String, String>> mylist,
            int textViewResourceId,
            String[] fieldNames,
            int[] fieldTargetIds) {
        super(c, mylist, textViewResourceId, fieldNames, fieldTargetIds );
        this.context = c;
        this.list = mylist;
        this.fieldNames = fieldNames;
        this.fieldTargetIds = fieldTargetIds;
        this.imageManager = new ImageManager(context.getApplicationContext());
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        View row = convertView;
        if (row == null) {
            LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            row = vi.inflate(R.layout.list, null);
        }
        //super.getView(position, convertView, parent);
        ImageView imgView = (ImageView) row.findViewById(R.id.doodlepic);

        try {
            String url = list.get(position).get("image");
            imgView.setTag(url);
            imageManager.displayImage(url, context, imgView);
        } catch (Exception e) {

        }

        for (int i=0; i<fieldNames.length; i++) {
            TextView tv = (TextView) row.findViewById(fieldTargetIds[i]);
            tv.setText(list.get(position).get(fieldNames[i]));              
        }


        return row;
    }

}

如何在生成和下载 json 对象时实现异步任务以显示进度对话框?我试过使用线程和异步任务,但我不太清楚如何将我的代码分解成适当的部分。

最佳答案

AsyncTask 的 onPreExecute 和 onPostExecute 将在 UI 线程中运行,doInBackground 将在另一个线程中运行,因此下面的代码应该适合您

public class YourActivity extends Activiy{
   public void getJson(String selection, String url) { 
           new LoadJsonTask().execute( selection, url);

   }
   private class LoadJsonTask extends AsyncTask<String, Void, ArrayList<HashMap<String, String>> > {
       ProgressDialog dialog ;
       protected void onPreExecute (){
            dialog = ProgressDialog.show(YourActivity.this ,"title","message");

       }
       protected ArrayList<HashMap<String, String>> doInBackground (String... params){
           return doGetJson(params[0],params[1]);
       }
       protected void onPostExecute(ArrayList<HashMap<String, String>> mylist){

            ListAdapter adapter = new JsonAdapter(YourActivity.this, mylist, R.layout.list,
              new String[] { "name", "text", "ts"}, new int[] { R.id.item_title,
                R.id.item_subtitle, R.id.timestamp});
            setListAdapter(adapter);
            dialog.dismiss();
       }
    }

 public ArrayList<HashMap<String, String>> doGetJson(String selection, String url) {
     JSONObject json = null;
     String formatedcat = selection.toLowerCase();
     ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
     json = JSONfunctions
        .getJSONfromURL(url);
     try {
    //the array title that you parse
    JSONArray category = json.getJSONArray(formatedcat);
    for (int i = 0; i < category.length(); i++) {               
        HashMap<String, String> map = new HashMap<String, String>();
        JSONObject c = category.getJSONObject(i);
        map.put("id", String.valueOf(i));
        map.put("name",
                c.getString("title"));
        //map.put("text",c.getString("title"));
        map.put("ts",c.getString("run_date") );
        map.put("image","http:"+c.getString("url"));
        mylist.add(map);
    }
} catch (JSONException e) {

}
   return mylist;
  ....   
}

关于android - 设置异步任务以将 Json 加载到 ListView 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9353700/

有关android - 设置异步任务以将 Json 加载到 ListView 中的更多相关文章

  1. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  2. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  3. ruby-openid:执行发现时未设置@socket - 2

    我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass

  4. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  5. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  6. ruby-on-rails - 如何使用 instance_variable_set 正确设置实例变量? - 2

    我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击

  7. ruby - 如何使用 RSpec::Core::RakeTask 创建 RSpec Rake 任务? - 2

    如何使用RSpec::Core::RakeTask初始化RSpecRake任务?require'rspec/core/rake_task'RSpec::Core::RakeTask.newdo|t|#whatdoIputinhere?endInitialize函数记录在http://rubydoc.info/github/rspec/rspec-core/RSpec/Core/RakeTask#initialize-instance_method没有很好的记录;它只是说:-(RakeTask)initialize(*args,&task_block)AnewinstanceofRake

  8. ruby-on-rails - Rails HTML 请求渲染 JSON - 2

    在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这

  9. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

    我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

  10. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

随机推荐