2

我正在尝试将我的一个应用程序转换为现在使用 Fragments。此应用程序还使用 Android 许可证检查器。在测试时,我将许可证检查器代码注释掉了,现在应用程序可以按我想要的方式运行。我现在准备取消注释该代码,以便将其放回市场,但是当我这样做时,我每隔一次启动应用程序时都会收到此消息:

java.lang.IllegalStateException:片段 MainHomeFragment{40544bd8} 未附加到 Activity

如果我在手机上或使用模拟器进行测试,就会发生这种情况。似乎许可证检查器完成的速度不够快,所以当它膨胀 Fragment 时,没有 Activity 可以附加它。起初我只是启动应用程序,然后在加载后按下后退按钮并立即再次尝试。我认为许可证检查器可能在第一次尝试时仍然在运行,所以下次我在使用返回键之前等待了 5 分钟,仍然遇到同样的问题。奇怪的是,在应用程序第二次炸毁后,如果我再次尝试它,它可以工作,但在第 4 次尝试它再次失败,所以不能从第一次成功的尝试中清除某些东西。如果我注释掉 LicenseChecker 代码并再次运行它,它每次都能正常工作。我尝试将对 LicenseChecker 的调用作为线程放在一个新类中,这样它就不会阻止正在创建的活动,但仍然会遇到同样的问题。关于我应该尝试解决这个问题的任何想法?

这是我的主要 FragmentActivity 的 onCreate 代码:

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

  ConnectivityManager connectivityManager 
    = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
  NetworkInfo activeNetwork = 
    connectivityManager.getActiveNetworkInfo();

  if (activeNetwork != null) { 
    android_id = Secure.getString(this.getContentResolver(), 
      Secure.ANDROID_ID);
    mObsfuscator = new AESObfuscator(SALT, getPackageName(), android_id);
    ServerManagedPolicy serverPolicy = new 
      ServerManagedPolicy(this, mObsfuscator);
    mLicenseCheckerCallback = new MyLicenseCheckerCallback();
    mChecker = new LicenseChecker(this, serverPolicy,
      BASE64_PUBLIC_KEY);
    mChecker.checkAccess(mLicenseCheckerCallback);
  } 

  setContentView(R.layout.fragment_layout);
}
4

2 回答 2

0

你为什么不首先做一个加载视图,然后在完成许可程序后,你用你的片段setContentView做“真正的” ?setContentView

我认为这可以正常工作。

于 2011-10-26T20:09:23.263 回答
0

我知道这真的很老了,但我仍然会投入我的 2 美分。

在您的问题中不清楚您是如何添加的Fragment(无论是通过 XML<fragment>标记,还是使用FragmentTransaction. 无论您在做什么,如果您只想Fragment在某种情况下添加(如果许可证检查器返回 OK 或其他)我'd 建议您以编程方式添加片段。

所以基本上,在 a 或任何其他布局中定义您的“正在加载...”视图FrameLayout,然后用 aFragmentTransaction替换该布局对象中的任何内容Fragment

我这样做的方法是使用Thread. 我AsyncTask非常不喜欢,因为它使所有后台作业共享一个线程。它使同步更容易一些,但如果你有很多下载/网络作业,它确实会影响性能,例如,因为它会一个接一个地排队,并且启动一个长作业会延迟所有其他后台作业执行。

我定义了两个Runnable对象 ( implements Runnable),因为您需要在 UI 线程上执行另一个对象(如果您从后台线程操作 UI,您会得到一个Exception)。

所以基本上,在Runnable将由 执行的第一个对象中Thread,您会收到对调用的引用Activity,并将其保存为实例变量。然后,您使用该引用在 UI 线程上执行第二个Runnable对象,如下所示(我在方法的末尾执行此操作runcallingActivity.runOnUiThread(new RunnableToRunOnUIThread());并在其中以Fragment编程方式添加。

于 2013-12-20T13:30:40.527 回答