Implementing a WebView within a CardView using a RecyclerView [duplicate] - android

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
I am using a WebView within a CardView with Recyclerview.
I implemented them correctly, but the problem is that when I run application it crashes and shows a nullpointer exception,
Log crash report:
java.lang.RuntimeException: Unable to start activity ComponentInfo{andro.petrochemical/andro.petrochemical.webViewNews}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.webkit.WebView.setWebViewClient(android.webkit.WebViewClient)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.webkit.WebView.setWebViewClient(android.webkit.WebViewClient)' on a null object reference
at andro.petrochemical.webViewNews.onCreate(webViewNews.java:33)
at android.app.Activity.performCreate(Activity.java:6662)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2599)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707) 
at android.app.ActivityThread.-wrap12(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6077) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755) 
WebView CardView xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/webView_news"/>
</LinearLayout>
</android.support.v7.widget.CardView>
RecyclerView xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
android:id="#+id/resycleWeb"/>
</LinearLayout>
WebView java class file:
public class webViewNews extends AppCompatActivity {
private WebView webviewthis;
private RecyclerView webVieRes;
private DatabaseReference mdataRef;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.webview_page);
webVieRes = (RecyclerView) findViewById(R.id.resycleWeb);
mdataRef = FirebaseDatabase.getInstance().getReference().child("weber");
webviewthis = (WebView)findViewById(R.id.webView_news);
webviewthis.setWebViewClient(new WebViewClient());
webviewthis.getSettings().setJavaScriptEnabled(true);
webviewthis.getSettings().setLoadsImagesAutomatically(true);
}
#Override
public void onStart() {
super.onStart();
FirebaseRecyclerAdapter<post2web,post2webViewHolder> firebaseRecyclerAdapte = new FirebaseRecyclerAdapter<post2web,post2webViewHolder>(
post2web.class,
R.layout.web_card,
post2webViewHolder.class,
mdataRef
) {
#Override
protected void populateViewHolder(post2webViewHolder viewHolder, post2web model, int position) {
viewHolder.setWebViewPost(model.getWebViewPost());
}
};
webVieRes.setAdapter(firebaseRecyclerAdapte);
}
public static class post2webViewHolder extends RecyclerView.ViewHolder {
View mVie;
public post2webViewHolder(View itemView) {
super(itemView);
mVie = itemView;
}
public void setWebViewPost(String webViewPost) {
WebView post_web = (WebView) mVie.findViewById(R.id.webView_news);
post_web.loadUrl(webViewPost);
}
}
}

Remove webview initialization from onCreate()
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.webview_page);
webVieRes = (RecyclerView) findViewById(R.id.resycleWeb);
mdataRef = FirebaseDatabase.getInstance().getReference().child("weber");
}
And update in post2webViewHolder
public void setWebViewPost(String webViewPost) {
WebView post_web = (WebView) mVie.findViewById(R.id.webView_news);
post_web.loadUrl(webViewPost);
post_web.setWebViewClient(new WebViewClient());
post_web.getSettings().setJavaScriptEnabled(true);
post_web.getSettings().setLoadsImagesAutomatically(true);
}

You need to only find the WebView from the post2webViewHolder
It's not part of the Activity, therefore it's null
Remove webviewthis

Related

Attempt to invoke virtual method 'void com.google.android.gms.ads.AdView.loadAd(com.google.android.gms.ads.AdRequest)' on a null object reference [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
i have been trying to show adbob banner ad in one of my activities but i keep getting this weird error, i tried doing different things but none of them helped fix the problem, i am stuck on this please help me fix this error, Thank you.
here is the logcat
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.rewardoapps.network/com.rewardoapps.network.ChatActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.google.android.gms.ads.AdView.loadAd(com.google.android.gms.ads.AdRequest)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.google.android.gms.ads.AdView.loadAd(com.google.android.gms.ads.AdRequest)' on a null object reference
at com.rewardoapps.network.ChatActivity.onCreate(ChatActivity.java:44)
at android.app.Activity.performCreate(Activity.java:6975)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892) 
at android.app.ActivityThread.-wrap11(Unknown Source:0) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593) 
at android.os.Handler.dispatchMessage(Handler.java:105) 
at android.os.Looper.loop(Looper.java:164) 
at android.app.ActivityThread.main(ActivityThread.java:6541) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) 
here is my ChatActivity.java activity
public class ChatActivity extends ActivityBase implements MsgImageChooseDialog.AlertPositiveListener {
private AdView AdView;
Toolbar mToolbar;
Fragment fragment;
Boolean restore = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dialogs);
mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
MobileAds.initialize(this,
"ca-app-pub-3940256099942544~3347511713");
AdRequest adRequestBanner = new AdRequest.Builder().build();
AdView = (AdView)this.findViewById(R.id.adView);
AdView.loadAd(adRequestBanner);
if (savedInstanceState != null) {
fragment = getSupportFragmentManager().getFragment(savedInstanceState, "currentFragment");
restore = savedInstanceState.getBoolean("restore");
} else {
fragment = new ChatFragment();
restore = false;
}
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container_body, fragment)
.commit();
}
.xml layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
xmlns:ads="http://schemas.android.com/apk/res-auto"
android:layout_height="match_parent" android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.rewardoapps.network.ChatActivity" >
<LinearLayout android:id="#+id/container_toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <include android:id="#+id/toolbar" layout="#layout/toolbar" /> </LinearLayout>
<LinearLayout
android:id="#+id/container_a"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#00ffffff"
android:gravity="bottom|center_vertical|center_horizontal"
android:orientation="vertical"
android:visibility="visible">
<com.google.android.gms.ads.AdView
android:id="#+id/adView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
ads:adSize="BANNER"
ads:adUnitId="ca-app-pub-3940256099942544/6300978111"></com.google.android.gms.ads.AdView>
</LinearLayout>
<FrameLayout
android:id="#+id/container_body"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:visibility="visible" />
here is the ActivityBase.java
public class ActivityBase extends AppCompatActivity implements Constants {
public static final String TAG = "ActivityBase";
private ProgressDialog pDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initpDialog();
}
protected void initpDialog() {
pDialog = new ProgressDialog(this);
pDialog.setMessage(getString(R.string.msg_loading));
pDialog.setCancelable(false);
}
protected void showpDialog() {
if (!pDialog.isShowing()) {
try {
pDialog.show();
} catch (Exception e) {
e.printStackTrace();
}
}
}
protected void hidepDialog() {
if (pDialog.isShowing()) {
try {
pDialog.dismiss();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Do like this -
AdRequest adRequestBanner = new AdRequest.Builder().build();
AdView mAdView = getBaseContext().findViewById(R.id.adView);;
mAdView.loadAd(adRequestBanner)

Error in Saving Realtime Database in my Firebase Account

I've created an App where a user clicks on get Coins Buton, 10 Coins are added in the Texview. User has separate Login Interface. But when I integrated Firebase Realtime Saving Data, It gets Crash.
I want that whenever a User Clicks on getCoins button, Coins should be added in Text Field and these coins should also reflect in my Firebase Data.
Activity_Main Layout.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.Toolbar
android:id="#+id/main_toolbar_id"
android:layout_width="match_parent"
android:background="#color/colorPrimary"
android:layout_height="wrap_content">
</android.support.v7.widget.Toolbar>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="#+id/btn"
android:layout_width="200dp"
android:layout_height="66dp"
android:layout_gravity="center"
android:gravity="center"
android:text="GET COINS"
android:textSize="20sp"
android:textStyle="bold"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
/>
<TextView
android:id="#+id/edittext"
android:layout_width="317dp"
android:layout_height="50dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_gravity="center"
android:layout_marginTop="124dp"
android:gravity="center"
android:text="COINS: 0"
android:textSize="40sp"
android:textStyle="bold" />
</RelativeLayout>
</android.support.constraint.ConstraintLayout>
Main Activity Class
public class MainActivity extends AppCompatActivity {
int CoinAmount = 0;
private Toolbar mainToolbar;
private FirebaseAuth mAuth;
String myStringData;
Firebase myFirebase;
TextView myEditText;
Button btngetcoin;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myStringData = myEditText.getText().toString();
Firebase.setAndroidContext(this);
myFirebase = new Firebase("https://xpensive-b5178.firebaseio.com");
btngetcoin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Firebase myNewChild= myFirebase.child("PresentCoin");
}
});
btngetcoin= (Button)findViewById(R.id.btn);
myEditText = (TextView)findViewById(R.id.edittext);
final RewardedVideoAd RewardAd = MobileAds.getRewardedVideoAdInstance(this);
RewardAd.loadAd("ca-app-pub-3940256099942544/5224354917", new AdRequest.Builder().build());
MobileAds.initialize(this);
btngetcoin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(RewardAd.isLoaded()){
RewardAd.show();
}else{
RewardAd.loadAd("ca-app-pub-3940256099942544/5224354917", new AdRequest.Builder().build());
}
}
});
RewardAd.setRewardedVideoAdListener(new RewardedVideoAdListener() {
#Override
public void onRewardedVideoAdLoaded() {
}
#Override
public void onRewardedVideoAdOpened() {
}
#Override
public void onRewardedVideoStarted() {
}
#Override
public void onRewardedVideoAdClosed() {
}
#Override
public void onRewarded(RewardItem rewardItem) {
CoinAmount= CoinAmount +10;
myEditText.setText("COINS: "+ CoinAmount);
}
#Override
public void onRewardedVideoAdLeftApplication() {
}
#Override
public void onRewardedVideoAdFailedToLoad(int i) {
}
#Override
public void onRewardedVideoCompleted() {
}
});
Logcat Errors-
06-30 20:20:24.988 6074-6074/com.vikramgehlot.xpensive E/AndroidRuntime: FATAL EXCEPTION: main
   Process: com.vikramgehlot.xpensive, PID: 6074
   java.lang.RuntimeException: Unable to start activity ComponentInfo{com.vikramgehlot.xpensive/com.vikramgehlot.xpensive.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2687)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2753)
       at android.app.ActivityThread.access$1100(ActivityThread.java:186)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1609)
       at android.os.Handler.dispatchMessage(Handler.java:111)
       at android.os.Looper.loop(Looper.java:238)
       at android.app.ActivityThread.main(ActivityThread.java:6016)
       at java.lang.reflect.Method.invoke(Native Method)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:937)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:798)
    Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
       at com.vikramgehlot.xpensive.MainActivity.onCreate(MainActivity.java:45)
       at android.app.Activity.performCreate(Activity.java:6466)
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1113)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2640)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2753) 
       at android.app.ActivityThread.access$1100(ActivityThread.java:186) 
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1609) 
       at android.os.Handler.dispatchMessage(Handler.java:111) 
       at android.os.Looper.loop(Looper.java:238) 
       at android.app.ActivityThread.main(ActivityThread.java:6016) 
       at java.lang.reflect.Method.invoke(Native Method) 
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:937) 
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:798) 
If you want to save your data in firebase realtime database then you just need to do something like this
mDatabase = FirebaseDatabase.getInstance().getReference().child("Users").child(mAuth.getCurrentUser().getUid());
Take the reference of your database and then just save it like this
mDatabase.child("Key").setValue(value);
or you can take a reference from this link https://firebase.google.com/docs/database/android/read-and-write
The variable btngetcoin is not initialized with a reference to the button object you have. Move the following findViewById() code above your set setOnClickListener,
myFirebase = new Firebase("https://xpensive-b5178.firebaseio.com");
// you need to initialize this before attaching listener!!
btngetcoin= (Button)findViewById(R.id.btn);
btngetcoin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Firebase myNewChild= myFirebase.child("PresentCoin");
}
});

Data Binding in an Activity with a MapFragment

I would like to use Data Binding Library in one of my projects but I am getting an error in the activity who has a MapFragment. Not using data binding librery the code works perfectly
My xml main_activity file:
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="#+id/my_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:theme="#style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" />
<fragment
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.project.activities.MainActivity" />
</RelativeLayout>
</layout>
And the baseActivity related
public abstract class BaseActivity extends AppCompatActivity {
private ActivityMainBinding binding;
private Toolbar toolbar;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, getContentView());
setContentView(getContentView());//Crashes
getPresenter();
configureToolbar();
Log.d(Constans.LOG_TAG,"On create");
}
private void configureToolbar() {
toolbar = binding.myToolbar;
if (toolbar != null) {
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
}
#Override
protected void onStop() {
super.onStop();
Log.d(Constans.LOG_TAG,"On Stop");
}
#Override
protected void onResume() {
super.onResume();
Log.d(Constans.LOG_TAG,"On resume");
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
return super.onCreateOptionsMenu(menu);
}
protected abstract int getContentView();
protected abstract void getPresenter();
}
And the error I get is :
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.project.activities.MainActivity}: android.view.InflateException: Binary XML file line #18: Binary XML file line #18: Error inflating class fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2450)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2510)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1363)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5461)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: android.view.InflateException: Binary XML file line #18: Binary XML file line #18: Error inflating class fragment
at android.view.LayoutInflater.inflate(LayoutInflater.java:539)
at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
at android.support.v7.app.AppCompatDelegateImplV9.setContentView(AppCompatDelegateImplV9.java:284)
at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:140)
at com.project.activities.MainActivity.BaseActivity.onCreate(BaseActivity.java:21)
at android.app.Activity.performCreate(Activity.java:6251)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2403)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2510) 
at android.app.ActivityThread.-wrap11(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1363) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:148) 
at android.app.ActivityThread.main(ActivityThread.java:5461) 
at java.lang.reflect.Method.invoke(Native Method)
The error itself is on onCreate(Bundle savedInstanceState) method on
setContentView(getContentView());
What I am doing wrong?
remove this line
setContentView(getContentView());//Crashes
and pass your layout resource to
binding = DataBindingUtil.setContentView(this, R.id.main_activity);
Your app crashes because you are trying to get the ContentView while it's null.
You will always need to call setContentView in your before trying to call getContentView.
Try:
setContentView(R.id.YOUR_LAYOUT_ID);//Crashes
binding = DataBindingUtil.setContentView(this, getContentView());

Android buttons null pointer [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
I am trying to add an onClickListener to a button, but log cat outputs an error
Here is the log cat
FATAL EXCEPTION: main
Process: com.pk.a_loner, PID: 10539
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.pk.a_loner/com.pk.a_loner.main.gui.Connect}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2814)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2879)
at android.app.ActivityThread.access$900(ActivityThread.java:182)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1475)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6141)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at com.pk.a_loner.main.gui.Connect.init(Connect.java:20)
at com.pk.a_loner.main.gui.Connect.onCreate(Connect.java:53)
at android.app.Activity.performCreate(Activity.java:6374)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2767)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2879) 
at android.app.ActivityThread.access$900(ActivityThread.java:182) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1475) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:145) 
at android.app.ActivityThread.main(ActivityThread.java:6141) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194) 
The code below, should be fine?
package com.pk.a_loner.main.gui;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import com.pk.a_loner.R;
import com.pk.a_loner.main.networking.Broadcast;
import com.pk.a_loner.main.networking.Listen;
public class Connect extends AppCompatActivity {
private Button button_toggleBroadcast;
private Button button_listen;
private void init() {
this.button_toggleBroadcast = (Button) (findViewById(R.id.button));
this.button_toggleBroadcast.setOnClickListener(new Button.OnClickListener() {
#Override
public void onClick(View v) {
if (!Broadcast.isInBroadcast()) {
if (!Broadcast.isHasInit()) {
Broadcast.init();
}
Broadcast.broadcast();
} else {
Broadcast.halt();
}
}
});
this.button_listen = (Button) (findViewById(R.id.button2));
this.button_listen.setOnClickListener(new Button.OnClickListener() {
#Override
public void onClick(View v) {
if (!Listen.isInScan()) {
if (!Listen.isHasInit()) {
Listen.init();
}
Listen.scan();
} else {
Listen.halt();
}
}
});
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v("hello world", "this is a hello");
this.init();
setContentView(R.layout.activity_launcher);
}
}
and here is the xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
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"
tools:context=".main.gui.Connect">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Toggle broadcast"
android:id="#+id/button" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Listen 10 secs"
android:id="#+id/button2" />
</LinearLayout>
</RelativeLayout>
I checked the code, I did initialize the buttons before I add the listener, shouldn't be null? buttons also declared in xml.
The app currently crashes on startup.
Any help appreciated, many thanks.
Use this in your onCreate() instead:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v("hello world", "this is a hello");
setContentView(R.layout.activity_launcher);
this.init();
}
You need to initialise your views AFTER your layout has been inflated by setContentView()
call setContentView(R.layout.activity_launcher); before init();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v("hello world", "this is a hello");
setContentView(R.layout.activity_launcher);
this.init();
}

Null TextView object in a fragment

I'm working on dynamically setting a text of TextView in a fragment called 'ChallengeFragment' by creating a method that sets the text. Then, I call the method in FragmentActivity class to update the TextView. However, I am getting error that TextView object is null when the method is called. I am not sure why TextView is null.
Here's the logcat message:
16:36:02.437 4072-4072/eie.android.crunch E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: eie.android.crunch, PID: 4072
java.lang.RuntimeException: Unable to start activity ComponentInfo{eie.android.crunch/eie.android.crunch.ChallengePage}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2390)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5257)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at eie.android.crunch.ChallengeFragment.setNameText(ChallengeFragment.java:76)
at eie.android.crunch.ChallengePage.onCreate(ChallengePage.java:50)
at android.app.Activity.performCreate(Activity.java:5990)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2390)
            at android.app.ActivityThread.access$800(ActivityThread.java:151)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5257)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Here is the Fragment class (ChallengeFragment.java):
public class ChallengeFragment extends Fragment {
private Activity mActivity;
private TextView nameText;
private Handler handler =new Handler();
public ChallengeFragment() {
}
public void onAttach(Activity activity) {
super.onAttach(activity);
mActivity = activity;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
LayoutInflater lf = getActivity().getLayoutInflater();
View v = lf.inflate(R.layout.fragment_challenge, null);
nameText = (TextView) v.findViewById(R.id.user_name_text_view);
....
return v;
}
public void setNameText(String s) {
nameText.setText(s);
}
public TextView getNameText() {
return nameText;
}
}
And this is the code for FragmentActivity that updates the text of TextView (ChallengePage.java):
public class ChallengePage extends FragmentActivity {
private FriendChallengeFragment initialFriendHabit;
private ChallengeFragment friendHabit;
private ChallengeFragment myHabit;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_challenge);
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
myHabit = new ChallengeFragment();
initialFriendHabit = new FriendChallengeFragment();
myHabit.onAttach(ChallengePage.this);
initialFriendHabit.onAttach(ChallengePage.this);
fragmentTransaction
.replace(R.id.my_habit, myHabit ,"fragment_top")
.replace(R.id.friend_habit, initialFriendHabit, "fragment_bottom")
.commit();
Intent intent = getIntent();
String challengedUsername = intent.getStringExtra("username");
if(challengedUsername != null) {
friendHabit = new ChallengeFragment();
friendHabit.onAttach(ChallengePage.this);
fragmentTransaction.replace(R.id.friend_habit, friendHabit, "fragment_bottom");
friendHabit.setNameText(challengedUsername);
}
}
}
And this is the layout file that contains the fragment (fragment_challenge.xml):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/white"
android:id="#+id/user_name_text_view"
android:layout_gravity="center_horizontal"
android:text="User Name"
android:textSize="30dp"
android:layout_marginTop="30dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/white"
android:id="#+id/habit_name_text"
android:layout_gravity="center_horizontal"
android:text="Habit Name"
android:textSize="40dp"
android:layout_marginTop="20dp"/>
<ProgressBar
android:layout_height="wrap_content"
android:layout_width="312dp"
style="#android:style/Widget.ProgressBar.Horizontal"
android:id="#+id/progressBar"
android:layout_marginTop="50dp"
android:layout_gravity="center_horizontal"/>
</LinearLayout>
I've looked at other stackoverflow questions relating to this but could not find answers.
The problem is your fragment's setNameText() method is called before onCreateView() has run, so your TextView has not been initialized yet. You have to wait until later to set the name text.
If you always have the name text when you are creating and adding the fragment, then it's better to pass that as an argument to the fragment and have it set the text of the TextView at the appropriate time. Something like this:
public class ChallengeFragment extends Fragment {
public static ChallengeFragment newInstance(String name) {
ChallengeFragment fragment = new ChallengeFragment();
Bundle args = new Bundle();
args.putString("username", name);
fragment.setArguments(args);
return fragment;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
Bundle args = getArguments();
if (args != null) {
String name = args.getString("username");
nameText.setText(name);
}
}
// everything else
}
A few things to note:
Do not create a constructor. Fragments need to have a default (no argument) constructor so that Android can instantiate them. This newInstance pattern is typically regarded as the best practice.
Use onActivityCreated because at that time you know the Activity is created and that the fragment's view hierarchy has been created.
Fragment arguments persist across configuration changes, so you shouldn't need to do anything special for that.
Also, you should not be calling onAttach() yourself, that's a lifecycle method that the OS calls on your fragment.

Categories

Resources