After I successfully launching the following intent:
startActivity(new Intent(Intent.ACTION_VIEW, SOME_URL));
The browser boots up fine and loads the link, but when I try to return to my app the response is sluggish. When the app eventually launches I am met with a black screen, and finally an "Application Not Responding" dialog.
No errors in logcat, no obvious memory issues, nothing to indicate what I did wrong.
The activity that launches the intent is a pretty simple activity, with one fragment:
public class LinkActivity extends AppCompatActivity {
#BindView(R.id.toolbar) Toolbar mToolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_link);
ButterKnife.bind(this);
setSupportActionbar(mToolbar);
setupActionBar();
if(savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.content, LinkFragment.newInstance()).commit();
}
}
private void setupActionBar() {
ActionBar actionBar = getSupportActionBar();
if(actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setDisplayShowTitleEnabled(true);
}
}
}
And the fragment uses a combination of RxJava, RetroFit and Dagger ‡ to load a list of links:
public class LinkFragment extends Fragment {
#Inject RestService mRestService;
#BindView(R.id.recycler) RecyclerView mRecyclerView;
public static LinkFragment newInstance() {
return new LinkFragment();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_link, container, false);
Injector.getContextComponent().inject(this);
ButterKnife.bind(this, view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext());
mRecyclerView.addItemDecoration(new DividerDecoration(getContext());
mRecyclerView.setAdapter(new LinkAdapter(new ArrayList<>()));
mRestService.getLinks()
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::onNext, this::onError);
return view;
}
private void onNext(Response<Link> response) [
LinkAdapter adapter = new LinkAdapter(response.data());
adapter.setOnItemClickListener(this::onItemSelected);
mRecyclerView.swapAdapter(adapter, false);
}
private void onError(Throwable throwable) {
Timber.w(throwable, "Failed to obtain links");
}
private void onItemSelected(int position, View view, Link link) {
startActivity(new Intent(Intent.ACTION_VIEW, link.getUri());
}
}
After finding two similar questions with similar answers (How to spot app freeze causes when app is returning from pause state?, Android App freezes after implementing Google Firebase) suggesting that adding Google Play Services might be the culprit, I started to investigate.
Both answers suggested that I remove the following dependency:
compile 'com.android.gms:play-services:9.0.2'
But my application uses that dependency, as well as the following play services dependencies:
compile 'com.google.android.gms:play-services-wearable:9.0.2'
compile 'com.google.android.gms:play-services-gcm:9.0.2'
compile 'com.google.android.gms:play-services-location:9.0.2'
compile 'com.google.android.gms:play-services-analytics:9.0.2'
Previously, I had been using classes from both the core play services library and the wearable play services library in both my mobile module and my wear module. But I noticed that I had removed the need for the wear module in my mobile module, so I removed it from the mobile module (while keeping it in the wear module). Somehow, this fixed the issue.
I have no clue why, so if anyone has any thoughts, please share.
Related
I have 3 fragments in my app and I want to log every time one of them is displayed. This is what I have in the onResume() in each fragment class:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
AppController application = (AppController) getActivity().getApplication();
mTracker = application.getDefaultTracker();
}
#Override
public void onResume() {
super.onResume();
if (mTracker != null) {
mTracker.setScreenName("Fragment_1");
mTracker.send(new HitBuilders.ScreenViewBuilder().build());
mTracker.enableAdvertisingIdCollection(true);
}
Log.i("RESUME", "Fragment_1");
}
However, when the app is launched, I receive all the three logs and when I scroll to another fragment, the onResume is not activated. I believe what happens is when the app is launched then all three fragments are loaded (I see that the data are downloaded from my server to populate the lists in the other 2 even if I'm just looking at the first fragment) and that's why onResume is not called when I scroll to the other fragments.
This and this is no different from this approach.
I tried to make social module for my app, something like wrapper, that will contain Google+,Facebook and twitter integration templates.
Now I am working with Facebook SDK and decided to use LeakCanary in my app, after successful log in I rotated the device few times, and see the following information:
Here is MainActivity.class:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
setFragment();
}
private void setFragment(){
getSupportFragmentManager()
.beginTransaction()
.add(R.id.container, new MainFragment())
.commit();
}
}
Here is how I log in to Facebook:
public void configureFacebook(#NonNull Fragment fragment,
#Nullable String permissions, #Nullable String requestFields) {
setPermissionAndRequestFields(permissions, requestFields);
loginManager = LoginManager.getInstance();
callbackManager = CallbackManager.Factory.create();
loginManager.registerCallback(callbackManager, facebookCallback);
loginManager.logInWithReadPermissions(fragment, Arrays.asList(this.permissions));
loginManager=null;
}
I tried log in using Login Button too, in this case I catch this issue and new one, with following info:
Here is how I log in using LoginButton.class:
public void configureFacebook(#NonNull Fragment fragment,
#Nullable String permissions, #Nullable String requestFields, #NonNull LoginButton button) {
callbackManager = CallbackManager.Factory.create();
setFbButton(button);
setPermissionAndRequestFields(permissions, requestFields);
fbButton.setFragment(fragment);
fbButton.setReadPermissions(this.permissions);
fbButton.registerCallback(callbackManager, facebookCallback);
}
I can't figure out how to fix those issues. What I am doing wrong?
UPDATE: Leak in Facebook Activity.class has been shown without the rotation device.
Looks like they may have fixed this for Facebook SDK Version 4.2.0. see here
Updating the Facebook SDK may be the solution to your problem.
I updated it to 4.7.0 and I think this issue has been fixed.
Fixed in 4.10. I tried without facebook app and checked with memory manager.
I'm an iOS dev, with absolutely no experience with android, so forgive me if I have difficulty expressing my question:
I'm getting a Fatal Exception in an android app I'm tasked with maintaining.
Fatal Exception: java.lang.RuntimeException Unable to start activity ComponentInfo{…}: java.lang.NullPointerException
I can see from the crash report (attached below) that the crash is happening in one of my fragments in a method called "bindLocation"
Here is the line it's crashing on:
mLocationHeaderTextView.setVisibility(View.VISIBLE);
So clearly the problem is that mLocationHeaderTextview is null. mLocationHeaderTextView is injected using roboguice as follows:
#InjectView(R.id.filter_location_header)
TextView mLocationHeaderTextView;
Now, I think the error is caused by my textView not being 'injected'. After looking at the stack trace, I've determine that this is likely a result of onViewCreated() not getting called before bindLocation() is called.
This is where I'm getting lost, however. I'm very unfamiliar with android, so I'm not sure how it's possible that my onViewCreated method is getting skipped over. I've tried a million things on the device to try and reproduce this situation, but I am unable. No matter what user actions I can think to try, my onViewCreated method gets called and my variable is non-Null. Perhaps I'm misreading the stack trace. I'm hoping that my stack trace below provides enough information for y'all to help me, but if not, let me know what else I can tell you about the app. I cannot post my full source code (as it does not belong to me), but I will provide whatever information I can.
Thanks so much for your help!
From my FilterDrawerFragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_filter_drawer, container, false);
ButterKnife.inject(this, view);
return view;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mRulesHeaderReset.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
resetRules();
}
});
if (getActivity() != null && mDrawerLayout == null) {
mDrawerLayout = (DrawerLayout) getActivity().findViewById(R.id.filter_drawer_layout);
if (mDrawerLayout != null) {
mDrawerLayout.setDrawerListener(new DrawerLayout.DrawerListener() {
#Override
public void onDrawerSlide(View view, float v) {
}
#Override
public void onDrawerOpened(View view) {
NavigationUtils.invalidateOptionsMenu(getActivity());
}
#Override
public void onDrawerClosed(View view) {
notifyFiltersChanged();
NavigationUtils.invalidateOptionsMenu(getActivity());
}
#Override
public void onDrawerStateChanged(int i) {
}
});
// set a custom shadow that overlays the main content when the drawer opens
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.END);
}
}
mlocationChangeButton.setOnClickListener(this);
bindUI();
}
private void bindUI() {
if (isAdded() && mConfiguration != null) {
// bind the location
bindLocation();
…
}
}
private void bindLocation() {
if (isAdded() && mConfiguration != null && mConfiguration.isLocationEnabled()) {
// show the location related items
mLocationHeaderTextView.setVisibility(View.VISIBLE);//Crash reported here.
…
}
});
}
}
/**
* Users of this fragment must call this to update the filter configuration
*/
public void updateConfiguration(FilterConfiguration configuration) {
if (configuration != null && !configuration.equals(mConfiguration)) {
mConfiguration = configuration;
bindUI();
}
}
And updateConfiguration() is called from
LocationFinderFragment:
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (getArguments() != null) {
………
if (savedInstanceState == null) {
mFilterDrawerFragment = FilterDrawerFragment.newInstance();
getChildFragmentManager()
.beginTransaction()
.replace(R.id.filter_drawer, mFilterDrawerFragment)
.commit();
} else {
mFilterDrawerFragment = (FilterDrawerFragment) getChildFragmentManager().findFragmentById(R.id.filter_drawer);
}
………
);
…………………
populateFilters();
}
private void populateFilters() {
// these might be passed into the fragment
if (mFacets != null) {
FilterConfiguration config = new FilterConfiguration() {{
……………………
}};
mFilterDrawerFragment.updateConfiguration(config);
Now I think I see the problem.
In roboguice views are injected in onViewCreated().
onViewCreated() is called after onCreateView().
bindLocation() is called in onCreateView().
Hence, by this time views are not yet injected by roboguice.
Please try calling bindLocation() in onViewCreated() after call to super.
This is how I fixed this. As you are using ButterKnife. Without these Configuration ButterKnife throws NPE.
Before you use this library you have to do some configuration to ButterKnife Eclipse Configuration or
ButterKnife Android Studio Configuration
If you are using ADT and missing Annototion Processing Check out this to install Android Eclipse - Cannot see annotation processing option
I tried to made button that goes to webpages but when I lunch app it crushes. There are no errors tos. What to do? Mby there is a problem in XML?
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment())
.commit();
}
addButtonClickListener(); //Soc network buttons
}
public void addButtonClickListener() //soc network buttons
{
Button facebook = (Button)findViewById(R.id.Facebookpoga); //Facebook pogai
facebook.setOnClickListener(new OnClickListener(){
public void onClick(View arg)
{
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.facebook.com"));
startActivity(intent);
}
});
}
I had encountered a similar problem, lot of times while learning the basics of Android development. And I can tell that the problem is that, for some reasons findViewById(id) returns null. This started happening after an update when eclipse started including a Fragment layout with the main layout for each Activity.
I sorted out the problems by putting all such calls in onStart() instead of onCreate(). And I am sure that sorts out the problem for you to.
Do this:
protected void onStart(){
addButtonClickListener(); //Soc network buttons
}
Add this function after onCreate(), hope it helps. And yes, remove the listener call addButtonClickListener(); from onCreate().
I guess the problem may be because Fragment layout is not instantinated immediately after setContentView() which results in findViewById(R.id.Facebookpoga); to return null, because no such View with id R.id.Facebookpoga is created yet.
i want display FriendPickerFragment in other fragment but i get empty list please help i cant find any info about thay
this is layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<FrameLayout
android:id="#+id/friend_picker_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
and this is code of fragment
public class HomeFragment extends Fragment {
public static final Uri FRIEND_PICKER = Uri.parse("picker://friend");
private FriendPickerFragment friendPickerFragment;
private static final String TAG = "MainFragment";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View rootView = inflater.inflate(R.layout.home_fragment, container,
false);
FragmentManager manager = getActivity().getSupportFragmentManager();
Fragment fragmentToShow = null;
friendPickerFragment = new FriendPickerFragment();
friendPickerFragment
.setOnErrorListener(new PickerFragment.OnErrorListener() {
#Override
public void onError(PickerFragment<?> fragment,
FacebookException error) {
Toast.makeText(getActivity(), error.getMessage(),
Toast.LENGTH_SHORT).show();
}
});
friendPickerFragment
.setOnDoneButtonClickedListener(new PickerFragment.OnDoneButtonClickedListener() {
#Override
public void onDoneButtonClicked(PickerFragment<?> fragment) {
Toast.makeText(getActivity(), "Done",
Toast.LENGTH_SHORT).show();
}
});
fragmentToShow = friendPickerFragment;
manager.beginTransaction()
.replace(R.id.friend_picker_fragment, fragmentToShow).commit();
return rootView;
}
#Override
public void onStart() {
super.onStart();
try {
friendPickerFragment.loadData(false);
} catch (Exception ex) {
}
}
}
Facebook has released their new sdk recently to enhance the level of security purpose. The following are the few requirement to use facebook sdk in your app.
check this points first!!
The app should send for the submission and needs to get approval from facebook team to use facebook integration in your own app for listing friends details, accessing locations and to access other special permissions The approval formalities are similar like store listing app in the google play.
The application must be listed in the google play or you could able to integrate it as a test user(i.e like beta testing in google play).
The application should have a proper package name, launching activity, domain name, website url and email.
The app id registered must match with a app name and hash key must be generated for a user developing with different machines
The sample screenshots of the application, description, and app logo needs to be added
Once after the successful approval from the team it will show a active symbol near your app name.
Hope this help!!!