如何使 Android 代码块可重用?

How can I make this block of Android code reusable?

我需要在加载数据时在许多不同的活动中显示忙指示器。这不是一个难题,但我讨厌重复自己。基础 class 不是一个选项,因为我并不总是扩展相同的基础 activity.

protected void updateProgressDialog() {
    //we're going to keep the progress dialog around if anything's busy
    if (getBusy()) {
        if (mProgressDialog == null) {
            mProgressDialog = new ProgressDialog(this, R.style.ProgressDialog);
            mProgressDialog.show();
            mProgressDialog.setContentView(R.layout.progress_layout);
        }
    } else {
        if (mProgressDialog != null) {
            mProgressDialog.dismiss();
            mProgressDialog = null;
        }
    }
}

在public静态class

public static void updateProgressDialog(Context context, ProgressDialog mProgressDialog) {
//If you can't access getBusy(), you may want to use a boolean argument here
if (getBusy()) {
    if (mProgressDialog == null) {
        mProgressDialog = new ProgressDialog(context, R.style.ProgressDialog); //you might have to cast context, not sure
        mProgressDialog.show();
        mProgressDialog.setContentView(R.layout.progress_layout);
    }
} else {
    if (mProgressDialog != null) {
        mProgressDialog.dismiss();
        mProgressDialog = null;
    }
}
}

另一个答案是更好的练习。

首先,做一个BaseActivityupdateProgressDialog()方法放在里面。现在,用这个 BaseActivity.

扩展了你的 Activity
public class BaseActivity extends Activity {
     ...
    ProgressDialog mProgressDialog ;

    protected void updateProgressDialog() {
        //we're going to keep the progress dialog around if anything's busy
        if (getBusy()) {
            if (mProgressDialog == null) {
                mProgressDialog = new ProgressDialog(this, R.style.ProgressDialog);
                mProgressDialog.show();
                mProgressDialog.setContentView(R.layout.progress_layout);
            }
        } else {
            if (mProgressDialog != null) {
                mProgressDialog.dismiss();
                mProgressDialog = null;
            }
        }
    }
 ...
}

现在你的另一个Activity喜欢,

public class MyActivity extends BaseActivity {
     ...
  getBusy()
  {
    .. getBusy() work done
  }
 ...
}

因为我假设 getBusy() 方法在您的正常 activity 中可用。

Second,将其放入任何 Java class 并使 updateProgressDialog(Context context, boolean flag) 具有 activity 上下文和布尔参数

ProgressDialog mProgressDialog ;

    public void updateProgressDialog(Context context, boolean flag) {
        //we're going to keep the progress dialog around if anything's busy
        if (flag) {
            if (mProgressDialog == null) {
                mProgressDialog = new ProgressDialog(context, R.style.ProgressDialog); 
                mProgressDialog.show();
                mProgressDialog.setContentView(R.layout.progress_layout);
            }
        } else {
            if (mProgressDialog != null) {
                mProgressDialog.dismiss();
                mProgressDialog = null;
            }
        }
    }

现在从你的 activity 称呼它,

<Class_Object>.updateProgressDialog(this, getBusy()); //Here this refers to Activity reference

Third,它与 Second 相同,但不是 Normal Java Class 你必须将你的方法放在 Android 应用程序 Class 拥有它的上下文。所以不需要传递上下文,只传递第二个布尔参数,就是这样。

然后这样称呼它,(来自你的activity) ((<Your_Application_Class>)getApplicationContext()).updateProgressDialog(getBusy());

以上给出的答案非常清楚和正确。 但是,如果您不想将所有 classes 扩展到 BaseActivity,那么您可以 select 其他方法。在这里:-

  1. 创建一个 class(Say MyApplication),它将是 class Application 的 Subclass。
  2. 现在在清单中注册此 class,为此您只需将名称 属性(android:name=".MyApplication") 命名为已经存在的应用程序标签那里。
  3. 编写用于在 MyApplication 中显示和关闭 ProgressDialog 的代码 class。
  4. 就是这样,可以在您的应用程序的任何 activity 中使用它。

这是代码片段。

MyApplication.java

public class MyApplication extends Application {

static ProgressDialog progressDialog;

void showDialog(String title, String message) {

    if (progressDialog == null) {
        progressDialog = new ProgressDialog(getApplicationContext());
    }

    progressDialog.setTitle(title);
    progressDialog.setMessage(message);
    progressDialog.show();
}

void dismissDialog() {
    progressDialog.dismiss();
}

}

清单文件(我们刚刚应用了名称 属性。)

 <application android:name=".MyApplication"
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name=".MainActivity"
        android:label="@string/app_name" 
        android:launchMode="singleInstance">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <activity android:name=".SecondActivity"/>

MainActivity(Activity 我们将在其中使用 showDialog 和 dismissDialog。)

...
((MyApplication) getApplication()).showDialog("Hi", "This is message.");
((MyApplication) getApplication()).dismissDialog();
...

在这里您不需要编辑您的活动签名。您只需创建 SubClass of Application class 即可。

希望对您有所帮助!

谢谢。

这似乎是您的应用程序的设计问题:长时间的进程应该 运行 在后台线程而不是主线程。 Activity 的方法在主线程(其他名称 UI)中调用,如果您进行了长时间的处理,它会挂断 UI。

如果你想通知用户长时间的后台任务状态,你可以使用:

  • AsyncTask onProcessUpdate 和 onPostExecute 方法向 MainThread 发送通知并显示 processDialog
  • 使用某种事件总线将通知消息从后台线程发送到 ui 线程

异步任务示例:

public interface UserNotificationService {
    void showProgressBar();
    void hideProgressBar();
}

public class UserNotificationServiceImpl implements UserNotificationService {

    private Context ctx;
    private ProgressDialog mProgressDialog;        

    public UserNotificationServiceImpl(Context ctx) { 
        this.ctx = ctx;
    }

    @Override
    public void showProgressBar() {
        if(mProgressDialog == null) {
           mProgressDialog = new ProgressDialog(ctx, R.style.ProgressDialog);
           mProgressDialog.show();
           mProgressDialog.setContentView(R.layout.progress_layout);
        } 
    }

    @Override
    public void hideProgressBar() {
        if(mProgressDialog!=null) {
           mProgressDialog.dismiss();
           mProgressDialog = null;
        }
    }

}

后台任务:

public class ExampleTask extends AsyncTask<Void, Void, Void>     {

   private UserNotificationService notificationService;

   public ExampleTask(Context ctx) {
      notificationService = new UserNotificationServiceImpl(ctx);
   }

   @Override
   protected Void doInBackground(URL... urls) { 
      // ... do your long time work here ... 
   }

   @Override
   protected void onPreExecute () {
      notificationService.showProgressBar();
   }

   @Override
   protected void onPostExecute(Void result) {
      notificationService.hideProgressBar();
   }

}