当前位置: 首页 > 知识库问答 >
问题:

如何使用列表或网格适配器设置Volley

陶高峯
2023-03-14

我正在尝试制作的音乐播放器中使用Volley。

下面是我如何定义音乐播放器中的歌曲。我有一个带有一些属性的“歌曲对象”

SongObject {

    public String albumArtURI;

    // Some other attributes 
}

我使用albumArtURI用图像填充各种列表和网格视图。

要获取专辑ArtURI,我对其进行查询。如果URI不存在,我必须从Internet上拉取一个图像URL。

所以我设置了截取,从iTunes中提取JSON对象,解析对象,并获取它们的图像URL。

例如,这里是iTunesJSON对象URL,它是包含代表迈克尔杰克逊专辑的各种JSON对象的网页的地址。

String url = "https://itunes.apple.com/search?term=michael+jackson";

现在假设我想为我的所有歌曲使用来自这些JSON专辑对象之一的图像URL。如果我使用Picasso在我的列表和网格上生成图像,那么我需要在Volley的onACK方法中调用Picasso。如果有更好的方法,请告诉我。

这是我的列表适配器之一

SongObject songObject = songObjectList.get(position);

ViewHolder viewHolder; 

if (convertView == null) {
    viewHolder = new ViewHolder();
    LayoutInflater inflater = LayoutInflater.from(getContext());
    convertView = inflater.inflate(R.layout.item_list_view, parent, false);
    convertView.setTag(viewHolder);
} else {
    viewHolder = (ViewHolder) convertView.getTag();
}

viewHolder.albumArt = (ImageView) convertView.findViewById(R.id.album_art);

// Here I check if songObject.albumArtURI is null, and use Picasso 

if(songObject.albumArtURI != null){

    File f = new File(songObject.albumArtURI);
    Picasso.with(viewHolder.albumArt.getContext())
            .load(f)
            .transform(new CircleTransform())
            .placeholder(R.drawable.blackcircle)
            .into(viewHolder.albumArt);
} else {

// If songObject.albumArtURI is null, I use Picasso inside Volley's onResponse method 

VolleyClass vc = new VolleyClass(getContext());
vc.runVolley();

}

这里是. runVolley()方法

// Here I set up the request queu

RequestQueue requestQueue = Volley.newRequestQueue(ctx);

// Here I make an json object request 

JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(url, new Response.Listener<JSONObject>() {
    @Override

    // Here I use GSON in the onResponse method to parse the object(s)

    public void onResponse(JSONObject response) {
        if (response != null) {
            int resultCount = response.optInt("resultCount");
            if (resultCount > 0) {
                Gson gson = new Gson();
                JSONArray jsonArray = response.optJSONArray("results");
                if (jsonArray != null) {

                    // Here I parse the JSON object(s) into their Java class 

                    SongInfo[] JSONObjectsList = gson.fromJson(jsonArray.toString(), SongInfo[].class);

                    // Here I use Picasso 

                    Picasso.with(ctx)
                        .load(String.valueOf(JSONObjectsList[0].artworkUrl30))
                        .transform(new CircleTransform())
                        .placeholder(R.drawable.blackcircle)
                        .into(iv);
                }
            }
        }
    }
}, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        Log.e("LOG", error.toString());
    }
});

// Here I add the object request object to the queue

requestQueue。add(jsonObjectRequest);代码正在运行,但问题是我在运行时的帧速率非常糟糕,如果我在列表视图中滚动过快,我的应用程序就会崩溃。错误日志在这篇文章的底部。

错误的帧速率似乎不是由毕加索造成的。如果我在onResponse方法中注释掉毕加索代码,我会得到相同的行为。

我认为问题在于,我在列表适配器的每个新迭代中都创建了requestQueue的一个新实例。我尝试过使用单例方法,但没有成功。

如何设置Volley以使用我的列表适配器并处理大量jsonObjectRequest?

11-27 01:25:21.482 32167-32182/ I/art: Background sticky concurrent mark sweep GC freed 157894(7MB) AllocSpace objects, 62(5MB) LOS objects, 9% free, 63MB/69MB, paused 9.954ms total 196.412ms
11-27 01:25:21.502 32167-32167/ D/ViewRootImpl: ViewPostImeInputStage ACTION_DOWN
11-27 01:25:21.602 32167-32182/ W/art: Suspending all threads took: 8.316ms
11-27 01:25:21.662 32167-32182/ I/art: Background partial concurrent mark sweep GC freed 160421(7MB) AllocSpace objects, 36(3MB) LOS objects, 22% free, 55MB/71MB, paused 16.171ms total 156.768ms
11-27 01:25:21.672 32167-32182/ W/art: Suspending all threads took: 5.037ms
11-27 01:25:21.712 32167-32174/ W/art: Suspending all threads took: 36.212ms
11-27 01:25:21.732 32167-32182/ I/art: Background sticky concurrent mark sweep GC freed 6365(305KB) AllocSpace objects, 6(372KB) LOS objects, 12% free, 55MB/63MB, paused 11.009ms total 55.466ms
11-27 01:25:21.772 32167-32167/ D/ViewRootImpl: ViewPostImeInputStage ACTION_DOWN
11-27 01:25:21.862 32167-32167/ D/ViewRootImpl: ViewPostImeInputStage ACTION_DOWN
11-27 01:25:22.062 32167-32167/ D/ViewRootImpl: ViewPostImeInputStage ACTION_DOWN
11-27 01:25:22.102 32167-32182/ I/art: Background partial concurrent mark sweep GC freed 134151(6MB) AllocSpace objects, 47(4MB) LOS objects, 22% free, 55MB/71MB, paused 11.466ms total 128.496ms
11-27 01:25:22.362 32167-32167/ D/ViewRootImpl: ViewPostImeInputStage ACTION_DOWN
11-27 01:25:22.652 32167-32182/ I/art: Background sticky concurrent mark sweep GC freed 171943(7MB) AllocSpace objects, 86(7MB) LOS objects, 11% free, 59MB/67MB, paused 6.646ms total 90.801ms
11-27 01:25:22.662 32167-32167/ D/ViewRootImpl: ViewPostImeInputStage ACTION_DOWN
11-27 01:25:22.712 32167-32174/ W/art: Suspending all threads took: 33.982ms
11-27 01:25:22.742 32167-32182/ I/art: Background partial concurrent mark sweep GC freed 124437(6MB) AllocSpace objects, 24(2MB) LOS objects, 23% free, 52MB/68MB, paused 12.255ms total 87.884ms
11-27 01:25:22.932 32167-32167/ D/ViewRootImpl: ViewPostImeInputStage ACTION_DOWN
11-27 01:25:23.192 32167-32167/ D/ViewRootImpl: ViewPostImeInputStage ACTION_DOWN
11-27 01:25:23.192 32167-32167/ I/Choreographer: Skipped 127 frames!  The application may be doing too much work on its main thread.
11-27 01:25:23.342 32167-32182/ I/art: Background sticky concurrent mark sweep GC freed 152008(7MB) AllocSpace objects, 69(6MB) LOS objects, 12% free, 57MB/65MB, paused 11.857ms total 124.020ms
11-27 01:25:23.702 32167-32174/ W/art: Suspending all threads took: 29.615ms
11-27 01:25:23.772 32167-32182/ I/art: Background partial concurrent mark sweep GC freed 165355(7MB) AllocSpace objects, 26(3MB) LOS objects, 21% free, 56MB/72MB, paused 10.798ms total 159.423ms
11-27 01:25:23.852 32167-32182/ I/art: Background sticky concurrent mark sweep GC freed 16824(674KB) AllocSpace objects, 1(150KB) LOS objects, 12% free, 57MB/65MB, paused 7.395ms total 66.835ms
11-27 01:25:24.182 32167-32174/ W/art: Suspending all threads took: 10.983ms
11-27 01:25:24.562 32167-32182/ I/art: Background partial concurrent mark sweep GC freed 60495(2MB) AllocSpace objects, 15(2MB) LOS objects, 20% free, 62MB/78MB, paused 12.542ms total 196.419ms
11-27 01:25:24.632 32167-32182/ I/art: Background sticky concurrent mark sweep GC freed 6414(236KB) AllocSpace objects, 0(0B) LOS objects, 11% free, 63MB/71MB, paused 10.624ms total 67.043ms
11-27 01:25:24.932 32167-32167/ W/libc: pthread_create failed: couldn't allocate 1064960-byte stack: Out of memory
11-27 01:25:24.932 32167-32167/ E/art: Throwing OutOfMemoryError "pthread_create (1040KB stack) failed: Try again"
11-27 01:25:24.932 32167-32167/ D/AndroidRuntime: Shutting down VM
11-27 01:25:24.932 32167-32167/ E/AndroidRuntime: FATAL EXCEPTION: main
11-27 01:25:24.932 32167-32167/ E/AndroidRuntime: Process: , PID: 32167
11-27 01:25:24.932 32167-32167/ E/AndroidRuntime: java.lang.OutOfMemoryError: pthread_create (1040KB stack) failed: Try again
11-27 01:25:24.932 32167-32167/ E/AndroidRuntime:     at java.lang.Thread.nativeCreate(Native Method)
11-27 01:25:24.932 32167-32167/ E/AndroidRuntime:     at java.lang.Thread.start(Thread.java:1063)
11-27 01:25:24.932 32167-32167/ E/AndroidRuntime:     at com.android.volley.RequestQueue.start(RequestQueue.java:145)
11-27 01:25:24.932 32167-32167/ E/AndroidRuntime:     at com.android.volley.toolbox.Volley.newRequestQueue(Volley.java:79)
11-27 01:25:24.932 32167-32167/ E/AndroidRuntime:     at com.android.volley.toolbox.Volley.newRequestQueue(Volley.java:105)
11-27 01:25:24.932 32167-32167/ E/AndroidRuntime:     at com.android.volley.toolbox.Volley.newRequestQueue(Volley.java:115)
11-27 01:25:24.932 32167-32167/ E/AndroidRuntime:     at .ServiceHandler.runVolley(ServiceHandler.java:41)
11-27 01:25:24.932 32167-32167/ E/AndroidRuntime:     at .MyListAdapterTracks.getView(MyListAdapterTracks.java:119)
11-27 01:25:24.932 32167-32167/ E/AndroidRuntime:     at android.widget.AbsListView.obtainView(AbsListView.java:2825)
11-27 01:25:24.932 32167-32167/ E/AndroidRuntime:     at android.widget.ListView.makeAndAddView(ListView.java:1884)
11-27 01:25:24.932 32167-32167/ E/AndroidRuntime:     at android.widget.ListView.fillDown(ListView.java:713)
11-27 01:25:24.932 32167-32167/ E/AndroidRuntime:     at android.widget.ListView.fillGap(ListView.java:677)
11-27 01:25:24.932 32167-32167/ E/AndroidRuntime:     at android.widget.AbsListView.trackMotionScroll(AbsListView.java:7043)
11-27 01:25:24.932 32167-32167/ E/AndroidRuntime:     at android.widget.AbsListView$FlingRunnable.run(AbsListView.java:6481)
11-27 01:25:24.932 32167-32167/ E/AndroidRuntime:     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:777)
11-27 01:25:24.932 32167-32167/ E/AndroidRuntime:     at android.view.Choreographer.doCallbacks(Choreographer.java:590)
11-27 01:25:24.932 32167-32167/ E/AndroidRuntime:     at android.view.Choreographer.doFrame(Choreographer.java:559)
11-27 01:25:24.932 32167-32167/ E/AndroidRuntime:     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:763)
11-27 01:25:24.932 32167-32167/ E/AndroidRuntime:     at android.os.Handler.handleCallback(Handler.java:739)
11-27 01:25:24.932 32167-32167/ E/AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:95)
11-27 01:25:24.932 32167-32167/ E/AndroidRuntime:     at android.os.Looper.loop(Looper.java:145)
11-27 01:25:24.932 32167-32167/ E/AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:5944)
11-27 01:25:24.932 32167-32167/ E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Native Method)
11-27 01:25:24.932 32167-32167/ E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Method.java:372)
11-27 01:25:24.932 32167-32167/ E/AndroidRuntime:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
11-27 01:25:24.932 32167-32167/ E/AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
11-27 01:25:25.062 32167-2055/ A/libc: Fatal signal 11 (SIGSEGV), code 1, fault add

共有1个答案

窦英武
2023-03-14

我认为问题在于您总是为每个请求创建RequestQueues。如果是这种情况,请将程序更改为使用RequestQueue的一个公共实例。plz指的是列表适配器中的post-Volley Plus OutOfMemoryError

如何在方法之外声明Request estQueue Request estQueue并进入您首先检查的方法,如果是这种情况,则初始化它,否则只需发出您的请求。

public class VolleyAppController extends Application {

private RequestQueue mRequestQueue;

private static VolleyAppController sInstance;

@Override
public void onCreate() {
    super.onCreate();

    // initialize the singleton
    sInstance = this;
}

public static synchronized VolleyAppController getInstance() {
    return sInstance;
}

public RequestQueue getRequestQueue() {

    if (mRequestQueue == null) {
        mRequestQueue = Volley.newRequestQueue(getApplicationContext());
    }

    return mRequestQueue;
}

public void addToRequestQueue(Request req) {

    getRequestQueue().add(req);
 }
}

现在您可以这样使用它:

JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(url, new Response.Listener<JSONObject>() {
@Override

// Here I use GSON in the onResponse method to parse the object(s)

public void onResponse(JSONObject response) {
    if (response != null) {
        int resultCount = response.optInt("resultCount");
        if (resultCount > 0) {
            Gson gson = new Gson();
            JSONArray jsonArray = response.optJSONArray("results");
            if (jsonArray != null) {

                // Here I parse the JSON object(s) into their Java class 

                SongInfo[] JSONObjectsList = gson.fromJson(jsonArray.toString(), SongInfo[].class);

                // Here I use Picasso 

                Picasso.with(ctx)
                    .load(String.valueOf(JSONObjectsList[0].artworkUrl30))
                    .transform(new CircleTransform())
                    .placeholder(R.drawable.blackcircle)
                    .into(iv);
            }
        }
    }
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
    Log.e("LOG", error.toString());
}
});

VolleyAppController.getInstance().addToRequestQueue(jsonObjectRequest);

希望对你有所帮助。

 类似资料:
  • 我有两个片段:(1)图书馆片段,(2)书片段 图书馆碎片通过RecyclerView显示所有可用的书籍。用户可以在每个RecyclerView项目上设置标签,这将把LiveData设置为相应的图书。同时,书籍片段将被打开,并显示该书的内容。 我在ViewHolder类中设置了一个onClickListener,它位于图书馆片段的RecyclerView. Adapter中。因此,当单击一个项目时,

  • 我在android应用程序上使用自定义适配器查看列表。我不知道如何设置项目单击的侦听器。我的应用程序使用Kotlin。 这是我的适配器布局。 有人可以帮助我吗?

  • 本文向大家介绍使用Element UI表格如何设置列宽的宽度自适应?相关面试题,主要包含被问及使用Element UI表格如何设置列宽的宽度自适应?时的应答技巧和注意事项,需要的朋友参考一下 https://kuaizi-co.github.io/kz-table/ 列宽自适应

  • Serenity 2.1.5 引入保存如下信息的网格列表设置: 可见列和显示顺序 列宽 排序的列 高级过滤器(由右下角的编辑过滤器链接创建) 快速过滤器(撰写本文档时,尚未提供该功能) 包含已删除的状态切换 默认情况下,网格列表不会自动持久化任何东西。 因此,如果你隐藏某些列并离开订单页面,当你再次返回该页面时,你就会看到那些隐藏的列再次成为可见列。 你需要开启所有网格列表的持久化设置,或设置单独

  • 如何使用适配器模式 横滑的滚动栏理论上应该是这个样子的: 新建一个 Swift 文件:HorizontalScroller.swift ,作为我们的横滑滚动控件, HorizontalScroller 继承自 UIView 。 打开 HorizontalScroller.swift 文件并添加如下代码: @objc protocol HorizontalScrollerDelegate { } 这

  • 我正在寻找在Android中使用列表适配器和Recyview适配器的区别。关于性能的任何不同,使用它们的利弊。