相关疑难解决方法(0)

在几个活动中重用Android AsnycTask的模式?

我的项目中有几个Activity子类,每个子类都调用一个基于SOAP的Web服务,处理并显示结果.SOAP序列化,调用处理和将结果解析为各种POJO对象都封装在MyWebService类中.该类通过AsyncTask执行实际的Web服务调用.

为了能够将结果传递回调用的Activity子类,我想我强制所有这些活动都应该实现一个WebServiceResultProcessor接口,定义一个函数(processWebServiceResults)作为AsyncTask的回调,从onPostExecute调用.

我还想在Web服务调用期间显示ProgressDialog.这是我的问题.为了能够显示ProgressDialog(来自MyWebService或它的AsyncTask),我需要传递对调用者Activity的Context的引用.并且为了能够从AsyncTask执行回调函数,我需要传递相同的对象引用,但这次是作为WebServiceResultProcessor.这在我看来是一种代码气味,两次传递相同的物体,但是看不到任何方法.我可以创建一个新的基类,扩展Activity类并从扩展类强制继承,而不是接口,但这意味着我将使用此MyWebService类排除ListActivity等.

有一个更好的方法吗?

android design-patterns reusability android-asynctask android-activity

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

是什么导致AsyncTask无法执行?

我的应用程序中有一个非常零星的失败,我正试图解决.在进入应用程序时,主UI线程处理结束并将控制权传递给后台线程以检索某些数据.检索数据时,控件会传回主UI线程进行处理以进行显示.然而,在一些罕见的场合(它在99%的时间内工作),AsyncTask似乎无法被调用,使应用程序处于一个不稳定的静态状态,永远等待AsyncTask完成.

这是以下代码的快照Activity:

//method call from main UI thread
private void fetchSomeData() {
    Log.d("myTag", "In fecthSomeData()");
    new ReadFileAsyncTask<DataModel>().execute(this);
}
Run Code Online (Sandbox Code Playgroud)

这是ReadFileAsyncTask实施:

public class ReadFileAsyncTask<A> extends AsyncTask<I_ReadFileListener<A>, Void, A>
{
I_ReadFileListener<A> listener;

@Override
@SuppressWarnings("unchecked")
protected A doInBackground(I_ReadFileListener<A>... params)
{
    listener = params[0];
    Log.d("mytag", "BACKGROUND: Loading " + listener.getFilename() + " from disk");
    A fileContents = (A) FileUtils.readDataFromInternalStorage(listener.getContext(), listener.getFilename());
    return fileContents;
}

@Override
protected void onPostExecute(A result)
{
    Log.d("myTag", "FOREGROUND: Executing onFileRetrieved listener");
    listener.onFileRetrieved(result);
}
}
Run Code Online (Sandbox Code Playgroud)

捕获这个罕见故障日志:

In fetchSomeData()
... …
Run Code Online (Sandbox Code Playgroud)

android android-asynctask

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

AsyncTask和运行时配置更改:Android团队认可哪些方法,简洁的代码示例?

自从2009 AsyncTask年在Cupcake(API 3,Android 1.5)中推出以来,它一直被Android团队一直推广为:

他们提供的代码示例强化了这种简单的信息,特别是对于那些不得不以更痛苦的方式使用线程的人.AsyncTask非常有吸引力.

然而,在此后的许多年里,崩溃,内存泄漏和其他问题困扰了大多数选择AsyncTask在其生产应用程序中使用的开发人员.这通常是由于Activity 破坏和娱乐上运行时配置的变化(特别是取向/旋转),而AsyncTask运行doInBackground(Params...); 当onPostExecute(Result)被调用时,Activity已经被破坏,使UI引用处于不可用状态(或甚至null).

Android团队在这个问题上缺乏明显,清晰,简洁的指导和代码样本只会让事情变得更糟,导致混乱以及各种变通方法和黑客攻击,有些体面,有些可怕:

显然,既然AsyncTask可以在很多情况下使用,那么就没有一种方法可以解决这个问题.然而,我的问题是关于选择.

什么是规范(由Android团队认可)最佳实践,使用简洁的代码示例,AsyncTaskActivity/ Fragmentlifecycle 集成并在运行时配置更改时自动重启?

android android-lifecycle android-configchanges android-asynctask android-memory

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

在没有 ViewModel 的情况下通过配置更改保留 CoroutineScope 的干净方法

我知道建议将 ViewModel 与我们的 Activity 一起使用,因此我们可以使用它的viewModelScope. 由于 ViewModel 比活动寿命更长,我们不必取消activity.onDestroy().

但是,有时您会遇到非常简单的 Activity。例如,它可以使用已安装的过滤包填充列表视图。您可以非常简单地使用委托为活动创建一个范围,并在onDestroy()以下位置取消作业:

class MyActivity(): AppCompatActivity(), CoroutineScope by MainScope() {

    private val listAdapter = MyAdapter()

    override fun onCreate() {
        super.onCreate()
        setContentView(R.layout.my_activity)
        recycler_view.apply {
            layoutManager = LinearLayoutManager(this)
            adapter = listAdapter
        }
        launch {
            val packages = getOrgPackagesWithIcons()
            adapter.apply {
                data = packages
                notifyDataSetChanged()
            }
        }

    }

    override fun onDestroy() {
        super.onDestroy()
        cancel() // CoroutineContext
    }

    private suspend fun getOrgPackagesWithIcons() = withContext(Dispatchers.Default) {
        var toNextYield = 20
        packageManager.getInstalledPackages(0)
            .filter …
Run Code Online (Sandbox Code Playgroud)

android kotlin kotlin-coroutines

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

在Handler中创建警报对话框

我想从一个处理程序创建一个警告对话框,当一个线程终止时,它会发出信号,这是我的代码导致:

android.view.WindowManager $ BadTokenException:无法添加窗口 - 令牌null不适用于应用程序

Handler handler = new Handler() {
      @Override
      public void handleMessage(Message msg) {

        if (dialog != null)
        {
            dialog.dismiss();
            dialog = null;
        }

        switch (serverResponseCode)
        {
        case 200:
        {
            AlertDialog alertDialog;
            alertDialog = new AlertDialog.Builder(getApplicationContext()).create();
            alertDialog.setTitle("Super :)");
            alertDialog.setMessage("Poza a fost trimisa cu success.");
            alertDialog.setButton("Ok", new DialogInterface.OnClickListener() {

                  public void onClick(DialogInterface dialog, int id) {

                     finish();

                } }); 
            alertDialog.show();
            serverResponseCode = -1;

            break;
        }
        default:
        {
            AlertDialog alertDialog;
            alertDialog = new AlertDialog.Builder(getApplicationContext()).create();
            alertDialog.setTitle("Eroare :(");
            alertDialog.setMessage("Eroare la …
Run Code Online (Sandbox Code Playgroud)

multithreading android

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

Android:如何在更改屏幕方向上禁用重新加载页面?

我有一项活动.我有一个过程,这很长.我改变了屏幕方向(纵向到横向),它们再次启动...我想在更改屏幕方向上禁用onCreate().

怎么让我这个?

android android-screen android-orientation android-activity

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