Getting error in existing code after updating supp

2019-01-28 20:54发布

When I am running my project using support libraries 23.0.0, I am not getting any error, but today when I updated my support repository to 23.1.0, the code of my activity is exactly same in both versions of using support libraries. I am getting the following error:

10-27 14:56:31.734 26271-26271/com.galleri5.android E/AndroidRuntime: FATAL EXCEPTION: main
10-27 14:56:31.734 26271-26271/com.galleri5.android E/AndroidRuntime: Process: com.galleri5.android, PID: 26271
10-27 14:56:31.734 26271-26271/com.galleri5.android E/AndroidRuntime: java.lang.IllegalArgumentException: Target must not be null.
10-27 14:56:31.734 26271-26271/com.galleri5.android E/AndroidRuntime:     at com.squareup.picasso.RequestCreator.into(RequestCreator.java:618)
10-27 14:56:31.734 26271-26271/com.galleri5.android E/AndroidRuntime:     at com.squareup.picasso.RequestCreator.into(RequestCreator.java:601)
10-27 14:56:31.734 26271-26271/com.galleri5.android E/AndroidRuntime:     at com.galleri5.android.activities.HomeActivity$3.success(HomeActivity.java:155)
10-27 14:56:31.734 26271-26271/com.galleri5.android E/AndroidRuntime:     at com.galleri5.android.activities.HomeActivity$3.success(HomeActivity.java:151)
10-27 14:56:31.734 26271-26271/com.galleri5.android E/AndroidRuntime:     at retrofit.CallbackRunnable$1.run(CallbackRunnable.java:45)
10-27 14:56:31.734 26271-26271/com.galleri5.android E/AndroidRuntime:     at android.os.Handler.handleCallback(Handler.java:739)
10-27 14:56:31.734 26271-26271/com.galleri5.android E/AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:95)
10-27 14:56:31.734 26271-26271/com.galleri5.android E/AndroidRuntime:     at android.os.Looper.loop(Looper.java:135)
10-27 14:56:31.734 26271-26271/com.galleri5.android E/AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:5254)
10-27 14:56:31.734 26271-26271/com.galleri5.android E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Native Method)
10-27 14:56:31.734 26271-26271/com.galleri5.android E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Method.java:372)
10-27 14:56:31.734 26271-26271/com.galleri5.android E/AndroidRuntime:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:898)
10-27 14:56:31.734 26271-26271/com.galleri5.android E/AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)
10-27 14:56:32.605 26271-26342/com.galleri5.android E/GAv4: Successfully bound to service but never got onServiceConnected callback

Here is the code of my Activity:

package com.galleri5.android.activities;

import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Color;
import android.graphics.Typeface;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.design.widget.NavigationView;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import com.facebook.AccessToken;
import com.facebook.FacebookSdk;
import com.facebook.login.LoginManager;
import com.galleri5.android.Galleri5Application;
import com.galleri5.android.R;
import com.galleri5.android.adapters.FeedAdapter;
import com.galleri5.android.api.FeedAPI;
import com.galleri5.android.api.UserAPI;
import com.galleri5.android.models.FeedItem;
import com.galleri5.android.models.User;
import com.galleri5.android.utils.CircleTransform;
import com.galleri5.android.utils.SourceType;
import com.galleri5.android.utils.TinyDB;
import com.galleri5.android.utils.Utils;
import com.github.clans.fab.FloatingActionMenu;
import com.google.android.gms.analytics.HitBuilders;
import com.google.android.gms.analytics.Tracker;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.picasso.Picasso;

import java.util.List;

import retrofit.Callback;
import retrofit.RequestInterceptor;
import retrofit.RestAdapter;
import retrofit.RetrofitError;
import retrofit.client.OkClient;
import retrofit.client.Response;
import uk.co.chrisjenx.calligraphy.CalligraphyContextWrapper;

public class HomeActivity extends AppCompatActivity {

    ListView listView;
    Toolbar toolbar;
    FeedAdapter adapter;
    private DrawerLayout mDrawer;
    String token;
    TinyDB tinyDB;
    int SELECT_FILE = 1;
    static int radius = Utils.dpToPx(90);
    FloatingActionMenu fab;
    List<FeedItem> list;
    int commentIndex, r;
    static boolean commented;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        FacebookSdk.sdkInitialize(getApplicationContext());
        setContentView(R.layout.activity_home);

        listView = (ListView) findViewById(R.id.listView);

        RequestInterceptor requestInterceptor = new RequestInterceptor() {
            @Override
            public void intercept(RequestFacade request) {
                request.addHeader("Accept", "application/json");
                request.addHeader("Authorization", "Token " + token);
            }
        };

        OkHttpClient okHttpClient = new OkHttpClient();
        RestAdapter restAdapter = new RestAdapter.Builder()
                .setClient(new OkClient(okHttpClient))
                .setLogLevel(RestAdapter.LogLevel.FULL)
                .setEndpoint(API)
                .setRequestInterceptor(requestInterceptor)
                .build();

        FeedAPI feedAPI = restAdapter.create(FeedAPI.class);
        feedAPI.getFeed(new Callback<List<FeedItem>>() {
            @Override
            public void success(List<FeedItem> feedItems, Response response) {
                Log.i("Retrofit Info", "Success");
                Log.i("Data", feedItems.toString());
                list = feedItems;
                adapter = new FeedAdapter(HomeActivity.this, list);
                listView.setAdapter(adapter);
            }

            @Override
            public void failure(RetrofitError error) {
                Log.i("Retrofit Error", "Feed Failed");
            }
        });

        if (android.os.Build.VERSION.SDK_INT >= 21) {
            Window window = getWindow();
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.setStatusBarColor(Color.parseColor("#e2b509"));
        }

        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        final ActionBar ab = getSupportActionBar();
        assert ab != null;

        ab.setHomeButtonEnabled(true);
        ab.setDisplayHomeAsUpEnabled(true);
        ab.setHomeAsUpIndicator(R.drawable.feed_ic_menu);

        // Find our drawer view
        mDrawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        toolbar.setNavigationIcon(R.drawable.feed_ic_menu);

        final Typeface opensans = Typeface.createFromAsset(getAssets(), "fonts/OpenSans-Regular.ttf");
        final ImageView navProfile = (ImageView) findViewById(R.id.navProfilePic);
        final TextView username = (TextView) findViewById(R.id.username);
        final TextView karma = (TextView) findViewById(R.id.textView89);



> UserAPI userAPI = restAdapter.create(UserAPI.class);
>             userAPI.getFeed("-1", "json", new Callback<User>() {
>                 @Override
>                 public void success(final User user, Response response) {
>                     Log.i("USER", "User API successful");
>                     Picasso.with(HomeActivity.this)
>                             .load(user.getDpUrl())
>                             .resize(radius, radius)
>                             .centerCrop()
>                             .transform(new CircleTransform())
>                             .into(navProfile);
>     
>                     username.setText(user.getFirstName());
>                     username.setTypeface(opensans);
>     
>                     karma.setText(String.format("%s Karma Points", Integer.toString(user.getKarma())));
>                     karma.setTypeface(opensans);
>                 }
>     
>                 @Override
>                 public void failure(RetrofitError error) {
>                     Log.i("USER", "User Profile Failed");
>                 }
>             });


        // Find our drawer view
        NavigationView nvDrawer = (NavigationView) findViewById(R.id.nav_view);
        // Setup drawer view
        setupDrawerContent(nvDrawer);

        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mDrawer.openDrawer(Gravity.LEFT);
            }
        });

        fab = (FloatingActionMenu) findViewById(R.id.fab);
        fab.setClosedOnTouchOutside(true);

        findViewById(R.id.fabFacebook).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                SourceType type = new SourceType(true, false, false);
                Intent intent = new Intent(HomeActivity.this, FbImageSelectionActivity.class);
                startActivity(intent);
            }
        });

        findViewById(R.id.fabAlbum).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                SourceType type = new SourceType(false, false, true);
                Intent intent = new Intent(
                        Intent.ACTION_PICK,
                        android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                intent.setType("image/*");
                startActivityForResult(
                        Intent.createChooser(intent, "Select File"),
                        SELECT_FILE);
            }
        });

        findViewById(R.id.imageView129).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(HomeActivity.this, SearchActivity.class);
                startActivity(intent);
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        //getMenuInflater().inflate(R.menu.menu_home, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }


    private void setupDrawerContent(NavigationView navigationView) {
        navigationView.setNavigationItemSelectedListener(
                new NavigationView.OnNavigationItemSelectedListener() {
                    @Override
                    public boolean onNavigationItemSelected(MenuItem menuItem) {
                        selectDrawerItem(menuItem);
                        return true;
                    }
                });
    }

    private void selectDrawerItem(MenuItem menuItem) {

        Intent intent;

        switch (menuItem.getItemId()) {
            case R.id.nav_home:
                break;
            case R.id.nav_studio:
                showUserProfile("-1");
                break;
            case R.id.nav_discover:
                intent = new Intent(HomeActivity.this, DiscoverActivity.class);
                startActivity(intent);
                finish();
                return;
            case R.id.nav_karma:
                intent = new Intent(HomeActivity.this, KarmaActivity.class);
                startActivity(intent);
                finish();
                break;
            case R.id.nav_help:
                intent = new Intent(HomeActivity.this, HelpActivity.class);
                startActivity(intent);
                break;
            case R.id.nav_privacy:
                intent = new Intent(HomeActivity.this, TermsAndPrivacyActivity.class);
                startActivity(intent);
                break;
            case R.id.nav_mode:
                intent = new Intent(HomeActivity.this, HelpModeActivity.class);
                startActivity(intent);
                finish();
                break;
            case R.id.nav_logout:
                fblogout();
                return;
            default:
                break;
        }

        // Highlight the selected item, update the title, and close the drawer
        menuItem.setChecked(false);
        //setTitle(menuItem.getTitle());
        mDrawer.closeDrawers();
    }

    private void fblogout() {
        if (AccessToken.getCurrentAccessToken() != null) {
            LoginManager.getInstance().logOut();
        }
        tinyDB.clear();
        Intent intent = new Intent(HomeActivity.this, SignInActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
        HomeActivity.this.finish();
    }

    public void showGallery(String thumbId) {
        Intent intent = new Intent(HomeActivity.this, GalleryActivity.class);
        intent.putExtra("ID", thumbId);
        startActivity(intent);
    }

    public void showImage(String photoId) {
        Intent intent = new Intent(HomeActivity.this, ImageActivity.class);
        intent.putExtra("ID", photoId);
        startActivity(intent);
    }

    public void showUserProfile(String userId) {
        Intent intent = new Intent(HomeActivity.this, UserProfileActivity.class);
        intent.putExtra("ID", userId);
        startActivity(intent);
    }

    public void showComments(String commentId, int position, int row) {
        commentIndex = position;
        r = row;
        Intent intent = new Intent(HomeActivity.this, CommentsActivity.class);
        intent.putExtra("ID", commentId);
        startActivity(intent);
    }

    public void showLikes(String fiveId) {
        Intent intent = new Intent(HomeActivity.this, HiFiveActivity.class);
        intent.putExtra("ID", fiveId);
        startActivity(intent);
    }

    public static void updateComment(boolean b) {
        commented = b;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            Uri selectedImageUri = data.getData();
            String[] projection = {MediaStore.MediaColumns.DATA};
            Cursor cursor = managedQuery(selectedImageUri, projection, null, null,
                    null);
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
            cursor.moveToFirst();

            String selectedImagePath = cursor.getString(column_index);

            Intent intent = new Intent(HomeActivity.this, AddCaptionActivity.class);
            intent.putExtra("file", selectedImagePath);
            startActivity(intent);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();

        // New code to update comment counter
        if(commented) {
            int numComments = list.get(r).getFeedPhotos().get(commentIndex).getNumComments();
            commented = false;
            list.get(r).getFeedPhotos().get(commentIndex).setNumComments(numComments + 1);
            adapter.notifyDataSetChanged();
        }

        if(fab.isOpened())
            fab.toggle(true);
    }

    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
            if(fab.isOpened())
                fab.toggle(true);
            else
                this.moveTaskToBack(true);
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    protected void attachBaseContext(Context newBase) {
        super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
    }
}

Could anyone please help me figure out what's happening? I am getting mad here. I want to use the new support library if possible. Thanks.

Edit I have highlighted the code that is causing the problem in support library 23.1.0, if I comment this code out, the app runs perfectly.

Edit Here is my manifest file :

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.galleri5.android" >

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

    <uses-feature
        android:name="android.hardware.camera"
        android:required="false" />

    <application
        android:name=".Galleri5Application"
        android:allowBackup="true"
        android:debuggable="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <receiver
            android:name="com.google.android.gms.analytics.AnalyticsReceiver"
            android:enabled="true" >
            <intent-filter>
                <action android:name="com.google.android.gms.analytics.ANALYTICS_DISPATCH" />
            </intent-filter>
        </receiver>

        <service
            android:name="com.google.android.gms.analytics.AnalyticsService"
            android:enabled="true"
            android:exported="false" />

        <receiver
            android:name="com.google.android.gms.analytics.CampaignTrackingReceiver"
            android:exported="true" >
            <intent-filter>
                <action android:name="com.android.vending.INSTALL_REFERRER" />
            </intent-filter>
        </receiver>

        <service android:name="com.google.android.gms.analytics.CampaignTrackingService" />

        <meta-data
            android:name="com.facebook.sdk.ApplicationId"
            android:value="@string/facebook_app_id" />

        <activity
            android:name=".activities.LaunchActivity"
            android:label="@string/app_name"
            android:screenOrientation="portrait" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.facebook.FacebookActivity"
            android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
            android:label="@string/app_name"
            android:theme="@android:style/Theme.Translucent.NoTitleBar" />
        <activity
            android:name=".activities.SignInActivity"
            android:label="@string/title_activity_sign_in"
            android:screenOrientation="portrait" >
        </activity>
        <activity
            android:name=".activities.HomeActivity"
            android:label="@string/title_activity_home"
            android:screenOrientation="portrait" >
        </activity>
        <activity
            android:name=".activities.DiscoverTalentsActivity"
            android:label="@string/title_activity_discover_talents"
            android:screenOrientation="portrait" >
        </activity>

        <meta-data
            android:name="io.fabric.ApiKey"
            android:value="494aaf4ca421e4bdd34df14063fae3a229af051c" />

        <activity
            android:name=".activities.UserStudioFansActivity"
            android:label="@string/title_activity_user_studio_fans"
            android:screenOrientation="portrait" >
        </activity>
        <activity
            android:name=".activities.UserStudioBookmarksActivity"
            android:label="@string/title_activity_user_studio_bookmarks"
            android:screenOrientation="portrait" >
        </activity>
        <activity
            android:name=".activities.UserStudioGalleriesActivity"
            android:label="@string/title_activity_user_studio_galleries"
            android:screenOrientation="portrait" >
        </activity>
        <activity
            android:name=".activities.UserHiFiveDetailsActivity"
            android:label="@string/title_activity_user_hi_five_details"
            android:screenOrientation="portrait" >
        </activity>
        <activity
            android:name=".activities.GalleryGridActivity"
            android:label="@string/title_activity_gallery_grid"
            android:screenOrientation="portrait" >
        </activity>
        <activity
            android:name=".activities.LeaderboardActivity"
            android:label="@string/title_activity_leaderboard"
            android:screenOrientation="portrait" >
        </activity>
        <activity
            android:name=".activities.GalleryFollowersActivity"
            android:label="@string/title_activity_gallery_followers"
            android:screenOrientation="portrait" >
        </activity>
        <activity
            android:name=".activities.AddNewGalleryActivity"
            android:label="@string/title_activity_add_new_gallery"
            android:screenOrientation="portrait" >
        </activity>
        <activity
            android:name=".activities.AllGalleriesActivity"
            android:label="@string/title_activity_all_galleries"
            android:screenOrientation="portrait"
            android:windowSoftInputMode="stateHidden" >
        </activity>
        <activity
            android:name=".activities.AddToNewGalleryActivity"
            android:label="@string/title_activity_add_to_new_gallery"
            android:screenOrientation="portrait" >
        </activity>
        <activity
            android:name=".activities.TermsAndPrivacyActivity"
            android:label="@string/title_activity_terms_and_privacy"
            android:screenOrientation="portrait" >
        </activity>
        <activity
            android:name=".activities.WinKarmaDummyActivity"
            android:label="@string/title_activity_win_karma_dummy"
            android:screenOrientation="portrait" >
        </activity>
        <activity
            android:name=".activities.HelpModeActivity"
            android:label="@string/title_activity_help_mode"
            android:screenOrientation="portrait" >
        </activity>
        <activity android:name=".activities.OverallLeaderboardActivity" >
        </activity>
        <activity android:name=".activities.SignInHelpActivity" >
        </activity>
    </application>

</manifest>

2条回答
成全新的幸福
2楼-- · 2019-01-28 21:49

Now with the 23.1.1 release of the design support library, you can use

View header = navigationView.getHeaderView(0)
ImageView navProfile = (ImageView) header.findViewById(R.id.navProfilePic);
查看更多
贼婆χ
3楼-- · 2019-01-28 21:56

Update: With the release of Design Support Library 23.1.1, the following method has been added to address this issue:

/**
 * Gets the header view at the specified position.
 *
 * @param index The position at which to get the view from.
 * @return The header view the specified position or null if the position does not exist in this
 * NavigationView.
 */
public View getHeaderView(int index) {
    ...
}

You can also retrieve the number of headers, in case you have more than one:

/**
 * Gets the number of headers in this NavigationView.
 *
 * @return A positive integer representing the number of headers.
 */
public int getHeaderCount() {
    ...
}

In other words, if you use the headerLayout attribute, you can now get access to the view using above method:

View header = navigationView.getHeaderView(0);
ImageView navProfile = (ImageView) header.findViewById(R.id.navProfilePic);

Original answer below left intact for background and/or educational purposes.


I'm going to make an educated guess and say that the following line is probably inflating a view from your NavigationView's header layout:

final ImageView navProfile = (ImageView) findViewById(R.id.navProfilePic);

Where the header layout is given to the NavigationView using:

app:headerLayout="@layout/nav_drawer_header"

If so, continue reading...

With the 23.1.0 release of the design support library, the internal implementation of NavigationView changed to leverage RecyclerView (rather than ListView). With that change, the header has now become another 'item' in the view, meaning it doesn't become available until after the initial layout pass. As such, with your current code, when the findViewById() lookup executes, the RecyclerView hasn't set up the header yet, and hence the result of the lookup ends up being null.

The 'issue' has been reported and the consensus is that getting the header view is going to be exposed with a new method on the NavigationView (most likely just called getHeaderView()). Until this is rolled out, there are two obvious workarounds I'm aware of.

Workaround #1:

Remove app:headerLayout and inflate and add the header view manually. Then use the resulting layout to look up any views in the header.

View header = navigationView.inflateHeaderView(R.layout.nav_drawer_header);
ImageView navProfile = (ImageView) header.findViewById(R.id.navProfilePic);

Workaround #2:

Don't inflate views until after the initial layout pass. This can easily be accomplished by posting a Runnable to the view's parent's internal message queue, so it gets executed after any pending messages.

View parent = (View) mNavigationView.getParent();
parent.post(new Runnable() {
    @Override public void run() {
        ImageView navProfile = (ImageView) mNavigationView.findViewById(R.id.navProfilePic);
    }
});

Personally, I'd go with #1.

Related:

查看更多
登录 后发表回答