Prof-Mohamed Atef Prof-Mohamed Atef - 2 months ago 19
Android Question

Recyclerview working correctly on activity while AsyncTask return null value when using Fragment and crash

all of the following code were working correctly on an activity, but after trying to use a Fragment, the debugger presents that it tries to invoke Fragments at first, then try to execute the AsyncTask class uncorrectly, which crashes and didn't get the input Stream value from the API . i searched different articles related to my problem, but i would like to take an advice here if u please, here is my code as follows :

activity_main.xml file code lines ( which contains the container that the fragment would be added or replaced with it ) :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/mainactivity_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.example.prof_mohamedatef.tabletfragments.MainActivity">

</LinearLayout>


main_fragment.xml file code lines :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.v7.widget.RecyclerView
android:id="@+id/card_recycler_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

</LinearLayout>


MainActivity java file which beginTransaction between the Container on the activity with the MainFragment layout as follows :

package com.example.prof_mohamedatef.tabletfragments;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MainFragment mainFragment=new MainFragment();
getFragmentManager().beginTransaction()
.add(R.id.mainactivity_container,mainFragment)
.commit();
}
}


MainFragment java file which is being inflated on the activity :

package com.example.prof_mohamedatef.tabletfragments;

import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;


/**
* Created by Prof-Mohamed Atef on 9/8/2016.
*/
public class MainFragment extends android.app.Fragment{

private static final String TAG = "RecyclerViewFragment";

public MainFragment() {}

RecyclerView mRecyclerView;
public ImagesAdapter mAdapter;

ArrayList<MovieEntity> list = new ArrayList<MovieEntity>();

final String now = "http://api.themoviedb.org/3/movie/popular?api_key=868bebbf76a3831f11b3985c703cf959";

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
update_START();
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View rootView=inflater.inflate(R.layout.main_fragment,container,false);
rootView.setTag(TAG);
mRecyclerView = (RecyclerView)rootView.findViewById(R.id.card_recycler_view);
// mRecyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getActivity(), 2);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setAdapter(mAdapter);
return rootView;
}

private void update_START() {
Fetch_Moview_data f_m_data = new Fetch_Moview_data();
f_m_data.execute(now);
}

public String main_List = "results";
public String POSTER_PATH = "poster_path";
public String VIDEO_ID = "id";
public String TITLE = "title";
public String OVERVIEW = "overview";
public String RELEASE_DATE = "release_date";
public String POPULARITY = "popularity";
public String VOTE_AVERAGE_="vote_average";

public String POSTER_PATH_STRING;
public String VIDEO_ID_STRING;
public String TITLE_STRING;
public String OVERVIEW_STRING;
public String RELEASE_DATE_STRING;
public String POPULARITY_STRING;
public String VOTE_AVERAGE_STRING;

public JSONObject MoviesJson;
public JSONArray moviesDataArray;
public JSONObject oneMovieData;

public class Fetch_Moview_data extends AsyncTask<String, Void, ArrayList<MovieEntity>> {

private final String LOG_TAG = Fetch_Moview_data.class.getSimpleName();

private ArrayList<MovieEntity> getMovieDataFromJson(String MoviesJsonStr)
throws JSONException {

MoviesJson = new JSONObject(MoviesJsonStr);
moviesDataArray = MoviesJson.getJSONArray(main_List);

list.clear();
for (int i = 0; i < moviesDataArray.length(); i++) {

// Get the JSON object representing a movie per each loop
oneMovieData = moviesDataArray.getJSONObject(i);

POSTER_PATH_STRING = oneMovieData.getString(POSTER_PATH);
VIDEO_ID_STRING = oneMovieData.getString(VIDEO_ID);
TITLE_STRING = oneMovieData.getString(TITLE);
OVERVIEW_STRING = oneMovieData.getString(OVERVIEW);
RELEASE_DATE_STRING = oneMovieData.getString(RELEASE_DATE);
POPULARITY_STRING = oneMovieData.getString(POPULARITY);
VOTE_AVERAGE_STRING=oneMovieData.getString(VOTE_AVERAGE_);

mAdapter=null;
MovieEntity entity = new MovieEntity(POSTER_PATH_STRING, VIDEO_ID_STRING, TITLE_STRING, OVERVIEW_STRING, RELEASE_DATE_STRING, POPULARITY_STRING,VOTE_AVERAGE_STRING);
list.add(entity);
}

return list;
}

@Override
protected ArrayList<MovieEntity> doInBackground(String... params) {

String Movies_images_JsonSTR = null;

HttpURLConnection urlConnection = null;
BufferedReader reader = null;

if (params.length == 0) {
return null;
}

try {

URL url = new URL(params[0]);
urlConnection = (HttpURLConnection) url.openConnection();

urlConnection.setRequestMethod("GET");
urlConnection.connect();

InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
Movies_images_JsonSTR = null;
}

reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line + "\n");
}
if (buffer.length() == 0) {
return null;
}

Movies_images_JsonSTR = buffer.toString();

Log.v(LOG_TAG, "Movies JSON String: " + Movies_images_JsonSTR);
} catch (IOException e) {
Log.e(LOG_TAG, "Error here Exactly ", e);

return null;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e(LOG_TAG, "Error closing stream", e);
}
}else {
Log.v(LOG_TAG, "Reader = null ( No Input Stream ) ");
}
}
try {
return getMovieDataFromJson(Movies_images_JsonSTR);
} catch (JSONException e) {
Log.e(LOG_TAG, "didn't got Movies Data from getJsonData method", e);
e.printStackTrace();
}
return null;
}

@Override
protected void onPostExecute(ArrayList<MovieEntity> result) {
mAdapter=null;
list=result;
mAdapter = new ImagesAdapter(getContext(), result);
mRecyclerView.setAdapter(mAdapter);
}
}
}


Edit
the problem is n't in the AsyncTask itself, however it doesn't fetch the movie data from the online API, but the problem is related to the Fragment which is used here, the debugger doesn't identify the type of the Exception, but i could identify that it didn't connect to server, so, the returned InputStream, StringBuffer, and the JsonString are null values.

the same code is working correctly when the recyclerview is initialized on the onCreate method on my activity class file, but on the fragment the app crashes without getting the Json String Array requested from the API. It crashes in the Async Task. Any pointers on where the problem is and what's required to perform in order to display the recyclerview successfully are appreciated. Thanks in advance.

second edit

E/dalvikvm: **Could not find class 'android.util.ArrayMap'**, referenced from method com.android.tools.fd.runtime.MonkeyPatcher.monkeyPatchExistingResources
09-09 21:04:48.351 26794-26794/com.example.prof_mohamedatef.tabletfragments W/dalvikvm: VFY: unable to resolve check-cast 2079 (Landroid/util/ArrayMap;) in Lcom/android/tools/fd/runtime/MonkeyPatcher;
09-09 21:04:48.351 26794-26794/com.example.prof_mohamedatef.tabletfragments D/dalvikvm: VFY: replacing opcode 0x1f at 0x0258
09-09 21:04:48.361 26794-26794/com.example.prof_mohamedatef.tabletfragments E/dalvikvm: Could not find class 'android.util.ArrayMap', referenced from method com.android.tools.fd.runtime.MonkeyPatcher.pruneResourceCacheandroid.app.Fragment.setAllowEnterTransitionOverlap, referenced from method com.example.prof_mohamedatef.tabletfragments.MainFragment.access$super
09-09 21:04:49.061 26794-26794/com.example.prof_mohamedatef.tabletfragments W/dalvikvm: VFY: unable to resolve virtual method 377: Landroid/app/Fragment;.setAllowEnterTransitionOverlap (Z)V
09-09 21:04:49.061 26794-26794/com.example.prof_mohamedatef.tabletfragments D/dalvikvm: VFY: replacing opcode 0x6f at 0x03d8
09-09 21:04:49.061 26794-26794/com.example.prof_mohamedatef.tabletfragments I/dalvikvm: **Could not find method android.app.Fragment.onInflate**, referenced from method com.example.prof_mohamedatef.tabletfragments.MainFragment.access$super
09-09 21:04:49.061 26794-26794/com.example.prof_mohamedatef.tabletfragments W/dalvikvm: VFY: unable to resolve virtual method 358: Landroid/app/Fragment;.onInflate (Landroid/content/Context;Landroid/util/AttributeSet;Landroid/os/Bundle;)V
09-09 21:04:49.061 26794-26794/com.example.prof_mohamedatef.tabletfragments D/dalvikvm: VFY: replacing opcode 0x6f at 0x0468
09-09 21:04:49.061 26794-26794/com.example.prof_mohamedatef.tabletfragments I/dalvikvm: Could not find method android.app.Fragment.getEnterTransition, referenced from method com.example.prof_mohamedatef.tabletfragments.MainFragment.access$super
09-09 21:04:49.061 26794-26794/com.example.prof_mohamedatef.tabletfragments W/dalvikvm: VFY: unable to resolve virtual method 311: Landroid/app/Fragment;.getEnterTransition ()Landroid/transition/Transition;
09-09 21:04:49.061 26794-26794/com.example.prof_mohamedatef.tabletfragments D/dalvikvm: VFY: replacing opcode 0x6f at 0x0499
09-09 21:04:49.071 26794-26794/com.example.prof_mohamedatef.tabletfragments E/dalvikvm: **Could not find class 'android.transition.Transition', referenced from method** com.example.prof_mohamedatef.tabletfragments.MainFragment.access$super
09-09 21:04:49.071 26794-26794/com.example.prof_mohamedatef.tabletfragments W/dalvikvm: VFY: unable to resolve check-cast 2075 (Landroid/transition/Transition;) in Lcom/example/prof_mohamedatef/tabletfragments/MainFragment;
09-09 21:04:49.071 26794-26794/com.example.prof_mohamedatef.tabletfragments D/dalvikvm: VFY: replacing opcode 0x1f at 0x04b5
09-09 21:04:49.071 26794-26794/com.example.prof_mohamedatef.tabletfragments I/dalvikvm: Could not find method **android.app.Fragment.getAllowEnterTransitionOverlap**, referenced from method com.example.prof_mohamedatef.tabletfragments.MainFragment.access$super
09-09 21:04:49.071 26794-26794/com.example.prof_mohamedatef.tabletfragments W/dalvikvm: VFY: unable to resolve virtual method 306: Landroid/app/Fragment;.getAllowEnterTransitionOverlap ()Z
09-09 21:04:49.071 26794-26794/com.example.prof_mohamedatef.tabletfragments D/dalvikvm: VFY: replacing opcode 0x6f at 0x04c9


Notice those Bold-formatted lines, what dos it means, this is the only reference i could get from this crash in the logCat. and there are no other Exception types.

Third Edit

09-11 14:25:14.968 3547-3714/com.example.prof_mohamedatef.tabletfragments E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
Process: com.example.prof_mohamedatef.tabletfragments, PID: 3547
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:309)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.SecurityException: Permission denied (missing INTERNET permission?)
at java.net.InetAddress.lookupHostByName(InetAddress.java:464)
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:252)
at java.net.InetAddress.getAllByName(InetAddress.java:215)
at com.android.okhttp.internal.Network$1.resolveInetAddresses(Network.java:29)
at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:188)
at com.android.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:157)
at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:100)
at com.android.okhttp.internal.http.HttpEngine.createNextConnection(HttpEngine.java:357)
at com.android.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:340)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:330)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:248)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:433)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:114)
at com.example.prof_mohamedatef.tabletfragments.MainFragment$Fetch_Movies_data.doInBackground(MainFragment.java:175)
at com.example.prof_mohamedatef.tabletfragments.MainFragment$Fetch_Movies_data.doInBackground(MainFragment.java:125)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
at java.lang.Thread.run(Thread.java:818) 
Caused by: android.system.GaiException: android_getaddrinfo failed: EAI_NODATA (No address associated with hostname)
at libcore.io.Posix.android_getaddrinfo(Native Method)
at libcore.io.ForwardingOs.android_getaddrinfo(ForwardingOs.java:55)
at java.net.InetAddress.lookupHostByName(InetAddress.java:451)
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:252) 
at java.net.InetAddress.getAllByName(InetAddress.java:215) 
at com.android.okhttp.internal.Network$1.resolveInetAddresses(Network.java:29) 
at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:188) 
at com.android.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:157) 
at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:100) 
at com.android.okhttp.internal.http.HttpEngine.createNextConnection(HttpEngine.java:357) 
at com.android.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:340) 
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:330) 
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:248) 
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:433) 
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:114) 
at com.example.prof_mohamedatef.tabletfragments.MainFragment$Fetch_Movies_data.doInBackground(MainFragment.java:175) 
at com.example.prof_mohamedatef.tabletfragments.MainFragment$Fetch_Movies_data.doInBackground(MainFragment.java:125) 
at android.os.AsyncTask$2.call(AsyncTask.java:295) 
at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
at java.lang.Thread.run(Thread.java:818) 
Caused by: android.system.ErrnoException: android_getaddrinfo failed: EACCES (Permission denied)
at libcore.io.Posix.android_getaddrinfo(Native Method) 
at libcore.io.ForwardingOs.android_getaddrinfo(ForwardingOs.java:55) 
at java.net.InetAddress.lookupHostByName(InetAddress.java:451) 
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:252) 
at java.net.InetAddress.getAllByName(InetAddress.java:215) 
at com.android.okhttp.internal.Network$1.resolveInetAddresses(Network.java:29) 
at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:188) 
at com.android.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:157) 
at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:100) 
at com.android.okhttp.internal.http.HttpEngine.createNextConnection(HttpEngine.java:357) 
at com.android.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:340) 
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:330) 
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:248) 
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:433) 
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:114) 
at com.example.prof_mohamedatef.tabletfragments.MainFragment$Fetch_Movies_data.doInBackground(MainFragment.java:175) 
at com.example.prof_mohamedatef.tabletfragments.MainFragment$Fetch_Movies_data.doInBackground(MainFragment.java:125) 
at android.os.AsyncTask$2.call(AsyncTask.java:295) 
at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
at java.lang.Thread.run(Thread.java:818) 


The Solution Exactely in this line of error :

Caused by: java.lang.SecurityException: Permission denied (missing INTERNET permission?)

Answer

I was missing the Internet Permission in my Manifest, just add :

<uses-permission android:name="android.permission.INTERNET" />

everything will work then correctly

Comments