简体   繁体   English

Android Recycler E/AndroidRuntime: FATAL EXCEPTION: main

[英]Android Recycler E/AndroidRuntime: FATAL EXCEPTION: main

I am trying to display a list of images inside a recyclerview.我正在尝试在 recyclerview 中显示图像列表。 However, when I add an image to my recycler, I receive a fatal error.但是,当我将图像添加到我的回收站时,我收到了一个致命错误。

I put my recycler inside a fragement:我把我的回收器放在一个片段中:

public class SearchOverviewFragment extends Fragment
{
    private RecyclerView recyclerView;
    private SearchDogAdapter searchDogAdapter;

    private final static String BREED_API = "https://dog.ceo/api/breed/{breed}/images";

    public SearchOverviewFragment()
    {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_search_overview, container, false);

        recyclerView = view.findViewById(R.id.searchRecycler);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

        ArrayList<String> test = new ArrayList<String>();
        test.add("https://images.dog.ceo/breeds/african/n02116738_9829.jpg");
        searchDogAdapter = new SearchDogAdapter(test, (MainActivity) getActivity());

        recyclerView.setAdapter(searchDogAdapter);

        return view;
    }

    public void setBreedURLList(String breed)
    {
        Log.e("URL", "Started");
        if(breed.equals(BreedConstants.DEFAULT_SELECTION))
        {
            searchDogAdapter.updateList(new ArrayList<String>());
            return;
        }

        URL url = null;
        try
        {
            url = new URL(BREED_API.replace("{breed}", breed));
        }
        catch (MalformedURLException e)
        {
            throw new Error("Malformed Breed URL");
        }
        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url.toString(), null,
            new Response.Listener<JSONObject>()
            {
                @Override
                public void onResponse(JSONObject response)
                {
                    try
                    {
                        JSONArray listdata = new JSONArray(response.getString("message"));
                        Log.e("ListData: ", String.valueOf(listdata.length()));
                        ArrayList<String> breedsURL = new ArrayList<>();
                        for (int i = 0; i < listdata.length(); i++)
                        {
                            Log.w("test", listdata.getString(i));
                            breedsURL.add(listdata.getString(i));
                        }

                        searchDogAdapter.updateList(breedsURL);

                    }
                    catch (JSONException jsonException)
                    {
                        jsonException.printStackTrace();
                    }
                }
            },
            new Response.ErrorListener()
            {
                @Override
                public void onErrorResponse(VolleyError error)
                {
                    error.printStackTrace();
                }
            });

        RequestQueue queue = Volley.newRequestQueue(getActivity());

        queue.add(jsonObjectRequest);
    }
}

My Adapter package com.example.mydogapplication.services.adapters;我的适配器package com.example.mydogapplication.services.adapters;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.recyclerview.widget.RecyclerView;

import com.example.mydogapplication.R;
import com.example.mydogapplication.controllers.MainActivity;
import com.example.mydogapplication.models.viewholders.SearchDogVH;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;

public class SearchDogAdapter extends RecyclerView.Adapter<SearchDogVH>
{
    private List<String> _breedsURL;
    private MainActivity _context;

    public SearchDogAdapter(List<String> breedsURL, MainActivity context){
        _breedsURL = breedsURL;
        _context = context;
    }

    @Override
    public SearchDogVH onCreateViewHolder(ViewGroup parent, int viewType)
    {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View view = inflater.inflate(R.layout.item_search_dog, parent, false);

        return new SearchDogVH(view);
    }

    @Override
    public void onBindViewHolder(SearchDogVH holder, int position)
    {
        URL url = null;
        try
        {
            url = new URL(_breedsURL.get(position));
            Bitmap bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream());
            holder.imageView.setImageBitmap(bmp);
        }
        catch (MalformedURLException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }

    @Override
    public int getItemCount()
    {
        return _breedsURL.size();
    }

    public void updateList(List<String> breedsURL)
    {
        _breedsURL.clear();

        _breedsURL.addAll(breedsURL);
        Log.e("Test: ", _breedsURL.toString());

        notifyDataSetChanged();
    }
}

ViewHolder视图持有者

package com.exampler.mydogapplication.models.viewholders;

import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import androidx.recyclerview.widget.RecyclerView;
import com.example.mydogapplication.R;


public class SearchDogVH extends RecyclerView.ViewHolder
{
    public ImageView imageView;
    public Button buttonView;

    public SearchDogVH(View view)
    {
        super(view);

        imageView = view.findViewById(R.id.imageSearchDog);
        buttonView = view.findViewById(R.id.buttonSearchDog);
    }
}

If I provide an empty arraylist the application starts without errors, but I receive the same Fatal Exception the moment setBreedURLList is called and an ArrayList with data is added to my Adapter.如果我提供一个空的 arraylist 应用程序启动时没有错误,但是我在调用setBreedURLList并且将带有数据的 ArrayList 添加到我的适配器时收到相同的致命异常。 Why is my application crashing when I add data to my Adaper?当我向 Adaper 添加数据时,为什么我的应用程序会崩溃?

UPDATE: Crashlog更新:崩溃日志

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.mydogapplication, PID: 10497
    android.os.NetworkOnMainThreadException
        at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1605)
        at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:115)
        at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:103)
        at java.net.InetAddress.getAllByName(InetAddress.java:1152)
        at com.android.okhttp.Dns$1.lookup(Dns.java:41)
        at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:178)
        at com.android.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:144)
        at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:86)
        at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:176)
        at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:128)
        at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:97)
        at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:289)
        at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:232)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:465)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:411)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:248)
        at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getInputStream(DelegatingHttpsURLConnection.java:211)
        at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:30)
        at com.example.mydogapplication.services.adapters.SearchDogAdapter.onBindViewHolder(SearchDogAdapter.java:46)
        at com.example.mydogapplication.services.adapters.SearchDogAdapter.onBindViewHolder(SearchDogAdapter.java:20)
        at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:7065)
        at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:7107)
        at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:6012)
        at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6279)
        at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6118)
        at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6114)
        at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2303)
        at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1627)
        at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1587)
        at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:665)
        at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4134)
        at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:3851)
        at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:4404)
        at android.view.View.layout(View.java:22844)
        at android.view.ViewGroup.layout(ViewGroup.java:6389)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
        at android.view.View.layout(View.java:22844)
        at android.view.ViewGroup.layout(ViewGroup.java:6389)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
        at android.view.View.layout(View.java:22844)
        at android.view.ViewGroup.layout(ViewGroup.java:6389)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1829)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1673)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1582)
        at android.view.View.layout(View.java:22844)
E/AndroidRuntime:     at android.view.ViewGroup.layout(ViewGroup.java:6389)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
        at android.view.View.layout(View.java:22844)
        at android.view.ViewGroup.layout(ViewGroup.java:6389)
        at androidx.appcompat.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:530)
        at android.view.View.layout(View.java:22844)
        at android.view.ViewGroup.layout(ViewGroup.java:6389)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
        at android.view.View.layout(View.java:22844)
        at android.view.ViewGroup.layout(ViewGroup.java:6389)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1829)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1673)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1582)
        at android.view.View.layout(View.java:22844)
        at android.view.ViewGroup.layout(ViewGroup.java:6389)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
        at com.android.internal.policy.DecorView.onLayout(DecorView.java:784)
        at android.view.View.layout(View.java:22844)
        at android.view.ViewGroup.layout(ViewGroup.java:6389)
        at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:3470)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2938)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1952)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8171)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:972)
        at android.view.Choreographer.doCallbacks(Choreographer.java:796)
        at android.view.Choreographer.doFrame(Choreographer.java:731)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:957)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

You are attempting to do network I/O on the main application thread.您正在尝试在主应用程序线程上执行网络 I/O。 This is banned by default, as it all but guarantees a poor user experience, as your UI is blocked while that I/O is ongoing.默认情况下这是禁止的,因为它只会保证糟糕的用户体验,因为在 I/O 进行时您的 UI 会被阻止。

A well-written image-loading library (Glide, Picasso, coil, etc.) will do the network I/O on a background thread, updating your ImageView on the main application thread only when the image is ready.一个编写良好的图像加载库(Glide、Picasso、线圈等)将在后台线程上执行网络 I/O,仅当图像准备好时才在主应用程序线程上更新您的ImageView

I solved my problem by using a NetworkImageView instead of a regular ImageView我通过使用 NetworkImageView 而不是常规 ImageView 解决了我的问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM