小编Gra*_*ith的帖子

实例化新Android片段的最佳实践

我已经看到了两个在应用程序中实例化新Fragment的一般实践:

Fragment newFragment = new MyFragment();
Run Code Online (Sandbox Code Playgroud)

Fragment newFragment = MyFragment.newInstance();
Run Code Online (Sandbox Code Playgroud)

第二个选项使用静态方法newInstance(),通常包含以下方法.

public static Fragment newInstance() 
{
    MyFragment myFragment = new MyFragment();
    return myFragment;
}
Run Code Online (Sandbox Code Playgroud)

起初,我认为主要的好处是我可以重载newInstance()方法以在创建Fragment的新实例时提供灵活性 - 但我也可以通过为Fragment创建重载构造函数来实现这一点.

我错过了什么?

一种方法比另一种方法有什么好处?还是只是好习惯?

android android-fragments

677
推荐指数
7
解决办法
30万
查看次数

如何在Android中获得圆形

如何通过Android形状drawable在Android中实现圆形,如下所示:

在此输入图像描述

android shape drawable

56
推荐指数
1
解决办法
9万
查看次数

如何使用Retrofit 2在单元测试期间创建retrofit.Response对象

在使用RxJava和Retrofit 2时,我正在尝试创建单元测试以覆盖我的应用程序何时收到特定响应.

我的问题是,使用Retrofit 2,我无法看到一个很好的方法来创建一个不使用反射的retrofit.Response对象.

@Test
public void testLogin_throwsLoginBadRequestExceptionWhen403Error() {


    Request.Builder requestBuilder = new Request.Builder();
    requestBuilder.get();
    requestBuilder.url("http://localhost");

    Response.Builder responseBuilder = new Response.Builder();
    responseBuilder.code(403);
    responseBuilder.protocol(Protocol.HTTP_1_1);
    responseBuilder.body(ResponseBody.create(MediaType.parse("application/json"), "{\"key\":[\"somestuff\"]}"));
    responseBuilder.request(requestBuilder.build());

    retrofit.Response<LoginResponse> aResponse = null;

    try {
        Constructor<retrofit.Response> constructor= (Constructor<retrofit.Response>) retrofit.Response.class.getDeclaredConstructors()[0];
        constructor.setAccessible(true);
        aResponse = constructor.newInstance(responseBuilder.build(), null, null);
    } catch (Exception ex) {
        //reflection error
    }

    doReturn(Observable.just(aResponse)).when(mockLoginAPI).login(anyObject());

    TestSubscriber testSubscriber = new TestSubscriber();
    loginAPIService.login(loginRequest).subscribe(testSubscriber);

    Throwable resultError = (Throwable) testSubscriber.getOnErrorEvents().get(0);
    assertTrue(resultError instanceof LoginBadRequestException);
}
Run Code Online (Sandbox Code Playgroud)

我尝试过使用以下内容,但这会创建一个OkHttp响应与一个Retrofit响应.

    Request.Builder requestBuilder = new Request.Builder();
    requestBuilder.get();
    requestBuilder.url("http://localhost");

    Response.Builder responseBuilder = new Response.Builder();
    responseBuilder.code(403); …
Run Code Online (Sandbox Code Playgroud)

android unit-testing mockito rx-java retrofit

37
推荐指数
3
解决办法
1万
查看次数

Android从BackStack中删除片段和视图

在此输入图像描述

我知道之前已经问过这个问题,但是到目前为止我已经得到了以前的答案.方案如下:我们有一个仪表板片段(A),它将用户引导到登录屏幕(B).成功登录后,他们会转到列表视图(c).在背压上我想返回A,因为用户不需要再次看到登录屏幕.此外,在成功登录后,我们将详细信息存储在共享首选项中,并在下次自动登录B,这些都按计划运行.

我有以下FragmentHelper方法:

public static void goToNextFragement(Fragment fragment, int container, boolean addToBackStack, Fragment ctx)
    {
        // Create new fragment and transaction
        FragmentTransaction transaction = ctx.getSupportFragmentManager().beginTransaction();
        transaction.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right);
        // Replace whatever is in the fragment_container view with this fragment,
        // and add the transaction to the back stack
        transaction.replace(container, fragment);

        if(addToBackStack)
            transaction.addToBackStack(null);

        // Commit the transaction
        transaction.commit();
    }
Run Code Online (Sandbox Code Playgroud)

在从B到CI的事务中,将布尔addToBackStack设置为false,以便transaction.addToBackStack(null);不调用它.这再次运作良好,但之后我的问题开始了.

当用户按下C并返回AI时,仍然可以在A的视图下看到C的膨胀视图.

任何帮助,将不胜感激.我希望我的图表有助于保持这一点.

android android-fragments

33
推荐指数
3
解决办法
3万
查看次数

测试RxBinding RxSearchView

背景

public Observable<List<Foo>> search(SearchView searchView) {

    return RxSearchView.queryTextChanges(searchView)
            .filter(charSequence -> !TextUtils.isEmpty(charSequence))
            .throttleLast(100, TimeUnit.MILLISECONDS)
            .debounce(200, TimeUnit.MILLISECONDS)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeOn(AndroidSchedulers.mainThread())
            .flatMap(this::performSearch) //Search the DB
            .onErrorResumeNext(this::doSomething);
}
Run Code Online (Sandbox Code Playgroud)

我试图用AndroidJUnit4跑步者测试上面的方法Mocktio.

@Test
public void testSearchCallsDataManager_WhenCalled() {

    String input = "abc";

    when(mockSearchView.getQuery()).thenReturn(input);

    searchRequestManager.search(mockSearchView).subscribe(testSubscriber); //Using standard TestSubscriber

    testSubscriber.assertNoErrors();
    testSubscriber.assertNotCompleted();
    verify(mockDataManager).getFoos(input);
}
Run Code Online (Sandbox Code Playgroud)

问题

我尝试过使用a mockSearchView和real SearchView.

mockSearchView = mock(SearchView.class);
searchView = new SearchView(InstrumentationRegistry.getContext(), null);
searchView = new SearchView(InstrumentationRegistry.getTargetContext(), null);
Run Code Online (Sandbox Code Playgroud)

在实例化期间,实际对象在测试运行时会导致不同的异常.模拟对象在执行期间似乎没有任何效果.

更新

为清楚起见:理想情况下,如果我可以模拟SearchView,那将是很好的,因为我想测试发生什么后发生的事情以及使用正确的输入调用performSearch方法.

android android-appcompat searchview rx-java rx-android

16
推荐指数
1
解决办法
847
查看次数

在Viewpager中映射v2 SupportMapFragment

背景

我成功地将新地图api v2.0添加到ViewPager并且地图加载正常.我正在使用FragmentViewPager.我遇到了麻烦,但是当我尝试添加标记时因为我无法获取Fragment by标签,因为我使用的ViewPager来自兼容性库并在XML中定义,这会"隐藏"我的标签.

问题

如何将带有标记的新Map v2加载SupportMapFragmentViewPager使用a的标记中FragmentPagerAdapter.

我的尝试

因此,我认为可以通过将SupportMapFragment扩展为执行以下操作的新类来创建一个优雅的解决方案:

  1. 添加一个带GoogleMapOptions和的新构造函数List<MarkerOptions>.这有效地调用了刚刚接受的现有构造函数,GoogleMapsOptions然后将我的标记列表存储在新类的私有属性中.
  2. 覆盖GetMap()- 检查它是否为空,如果它没有将标记添加到我们之前加载到地图上的地图,最后返回它.

我的想法是,我的扩展可以高度重用,并抽象出与一个地方相关的任何地图,并允许我的活动创建新的MapFragment newInstance(myGoogleMapOptions, myMarkers).

好的,这个问题.第1部分似乎工作正常但是在调试期间我无法调用重写的GetMap()方法.事实上,我已经尝试重写碎片拥有的大多数常用方法,但没有一个被调用.是否有一些奇怪的事情发生在SupportMapFragmemt上,我试图找到它的来源无济于事地检查自己.

更新

我意识到为什么我没有得到被覆盖的方法.这是因为我正在返回标准SupportMapFragment而不是MyMapFragment.也就是说我不能从静态方法调用super,并且我无法从基类转换为派生类而没有异常.

编辑 这是课程

public class MyMapFragment extends SupportMapFragment {

    private static List<MarkerOptions> mMarkers;

    public static SupportMapFragment newInstance(GoogleMapOptions options, List<MarkerOptions> markers)
    {
        SupportMapFragment fragment = newInstance(options);

        mMarkers = markers;

        return fragment;

    }

            //have tried Overriding several methods including getMap()...

    @Override
    public void onResume ()
    { …
Run Code Online (Sandbox Code Playgroud)

android android-maps android-fragments android-viewpager

14
推荐指数
1
解决办法
9629
查看次数

在Google Play商店中为自己的应用创建折扣代码

如果用户提供促销代码,谷歌游戏商店是否有可能免费下载(或有一定折扣)的非免费应用程序?

android discount

13
推荐指数
1
解决办法
6103
查看次数

如何从android有限间隔轮询web服务?

我正在开发一个Android应用程序来显示通知.如何以有限的间隔(例如间隔10分钟)轮询网络服务以检查任何更新并在android通知面板中显示为通知.

notifications android web-services android-alarms android-notifications

8
推荐指数
2
解决办法
1万
查看次数

使用Realm的RxJava多线程 - 从错误的线程访问Realm

背景

我在我的应用程序中使用Realm.当加载数据时,它将经历密集处理,因此处理在后台线程上进行.

使用的编码模式是工作单元模式,而Realm仅存在于DataManager下的存储库中.这里的想法是每个存储库可以有不同的数据库/文件存储解决方案.

我试过了什么

下面是我在FooRespository类中的一些类似代码的示例.

这里的想法是获得Realm的一个实例,用于查询感兴趣的对象的领域,返回它们并关闭领域实例.请注意,这是同步的,最后将对象从Realm复制到非托管状态.

public Observable<List<Foo>> getFoosById(List<String> fooIds) {

    Realm realm = Realm.getInstance(fooRealmConfiguration);

    RealmQuery<Foo> findFoosByIdQuery = realm.where(Foo.class);

    for(String id : fooIds) {

        findFoosByIdQuery.equalTo(Foo.FOO_ID_FIELD_NAME, id);
        findFoosByIdQuery.or();
    }

    return findFoosByIdQuery
            .findAll()
            .asObservable()
            .doOnUnsubscribe(realm::close)
            .filter(RealmResults::isLoaded)
            .flatMap(foos -> Observable.just(new ArrayList<>(realm.copyFromRealm(foos))));
}
Run Code Online (Sandbox Code Playgroud)

此代码稍后通过RxJava与繁重的处理代码一起使用:

dataManager.getFoosById(foo)
            .flatMap(this::processtheFoosInALongRunningProcess)
            .subscribeOn(Schedulers.io()) //could be Schedulers.computation() etc
            .subscribe(tileChannelSubscriber);
Run Code Online (Sandbox Code Playgroud)

阅读文档后,我的信念是上面应该有效,因为它不是异步的,因此不需要一个循环线程.我在同一个线程中获取了域的实例,因此它不在线程之间传递,也不是对象.

问题

当执行上述操作时,我得到了

领域从错误的线程访问.Realm对象只能在创建它们的线程上访问.

这似乎不对.我唯一能想到的是Realm实例池让我获得了一个使用主线程从另一个进程创建的现有实例.

java multithreading android realm rx-java

8
推荐指数
1
解决办法
1900
查看次数

isGooglePlayServicesAvailable导致Android 5中的TransactionTooLargeException

我发布Fabric报告称,在检查Google Play服务的可用性时,在Android 5设备上可能会发生崩溃,特别是在OnePlus,Sony和Zuk设备中.

我没有直接明确调用此代码,似乎是由Google自己的代码调用.

根据其他帖子,当包裹太大时会抛出异常,但由于我不控制该过程,我自己的代码不负责创建包裹.

我已查看Google Play服务和其他帖子的发布说明,但无济于事.欢迎任何建议.

Fatal Exception: java.lang.RuntimeException: Package manager has died
       at android.app.ApplicationPackageManager.getPackageInfo(ApplicationPackageManager.java:112)
       at com.google.android.gms.common.zzo.isGooglePlayServicesAvailable(Unknown Source)
       at com.google.android.gms.common.zze.isGooglePlayServicesAvailable(Unknown Source)
       at com.google.android.gms.common.GoogleApiAvailability.getInstance(Unknown Source)
       at com.google.android.gms.common.api.internal.zzbr.connect(Unknown Source)
       at com.google.android.gms.common.api.internal.zzbp.zzb(Unknown Source)
       at com.google.android.gms.common.api.internal.zzbp.handleMessage(Unknown Source)
       at android.os.Handler.dispatchMessage(Handler.java:98)
       at android.os.Looper.loop(Looper.java:135)
       at android.os.HandlerThread.run(HandlerThread.java:61)
Caused by android.os.TransactionTooLargeException
       at android.os.BinderProxy.transactNative(Binder.java)
       at android.os.BinderProxy.transact(Binder.java:496)
       at android.content.pm.IPackageManager$Stub$Proxy.getPackageInfo(IPackageManager.java:1876)
       at android.app.ApplicationPackageManager.getPackageInfo(ApplicationPackageManager.java:107)
       at com.google.android.gms.common.zzo.isGooglePlayServicesAvailable(Unknown Source)
       at com.google.android.gms.common.zze.isGooglePlayServicesAvailable(Unknown Source)
       at com.google.android.gms.common.GoogleApiAvailability.getInstance(Unknown Source)
       at com.google.android.gms.common.api.internal.zzbr.connect(Unknown Source)
       at com.google.android.gms.common.api.internal.zzbp.zzb(Unknown Source)
       at com.google.android.gms.common.api.internal.zzbp.handleMessage(Unknown Source)
       at android.os.Handler.dispatchMessage(Handler.java:98)
       at android.os.Looper.loop(Looper.java:135)
       at android.os.HandlerThread.run(HandlerThread.java:61)
Run Code Online (Sandbox Code Playgroud)

android google-play-services

6
推荐指数
1
解决办法
303
查看次数

使用RxJava测试Android领域 - "从没有Looper的线程打开"异常

我有以下代码,基于Realm提供的文档(https://realm.io/docs/java/latest/#rxjava)

public Observable<Foo> getFooById(String id) {

    realm = Realm.getInstance(realmConfiguration);

    return realm.where(Foo.class)
            .equalTo("id", id)
            .findFirstAsync()
            .asObservable()
            .filter(this::filterResult);
}
Run Code Online (Sandbox Code Playgroud)

这可以在应用程序中按预期工作,但是当涉及到测试时,事情变得有点棘手.我有以下测试(剥离以保持简单):

@Test
public void testRealmExample() {

    RealmConfiguration config = new RealmConfiguration.Builder(context)
            .name("test.realm")
            .inMemory()
            .build();

    DataManager dataManager = new DataManager(config);

    TestSubscriber<Foo> testSubscriber = new TestSubscriber<>();
    dataManager.getFoo("").observeOn(AndroidSchedulers.mainThread()).subscribe(testSubscriber);
    testSubscriber.assertNoErrors();
}
Run Code Online (Sandbox Code Playgroud)

执行测试时,会发生以下错误java.lang.IllegalStateException: Your Realm is opened from a thread without a Looper. Async queries need a Handler to send results of your query.

为了解决这个问题,我在Realm GitHub页面上读到他们使用注释@UiThreadTest强制测试在UI线程上运行,从我的理解是一个looper线程,因此这应该解决我的问题.我补充说:

@Rule
public final UiThreadTestRule …
Run Code Online (Sandbox Code Playgroud)

junit android unit-testing realm rx-java

5
推荐指数
1
解决办法
1123
查看次数

我如何从WebView获取页面源代码?

我如何从WebView获取网页的来源?

我只想在我的网页浏览中输入www.google.com,当我进入这个网站时,我想获得源代码

String a=........;(source) 
Run Code Online (Sandbox Code Playgroud)

android android-webview

3
推荐指数
3
解决办法
2万
查看次数

应用程序关闭后如何在片段中停止AsyncTask

如何在关闭应用程序后停止片段类中的AsyncTask.

这是我的情况:

MainActivity类

public class MainActivity extends FragmentActivity {

}
Run Code Online (Sandbox Code Playgroud)

BaseFragment类由Fragment扩展

public class BaseFragment extends Fragment {
    public MainActivity mActivity;


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

        mActivity       =   (ChatActivity)this.getActivity();

    }

    public boolean onBackPressed(){
        return false;
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data){

    }

    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
    }


}
Run Code Online (Sandbox Code Playgroud)

片段类

public class Fragment1 extends BaseFragment{


private  Update  task;
@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        toCallAsynchronous();

        return …
Run Code Online (Sandbox Code Playgroud)

android android-asynctask android-fragments android-activity

1
推荐指数
1
解决办法
6252
查看次数