跳过 844 帧!简单的 AlertDialog with Spinners 导致 MainThread 中的工作过多

Skipped 844 frames! Too much work in MainThread caused by simple AlertDialog with Spinners

我使用带有两个微调器的 AlertDialog,应用程序本身非常快,但是当我启动这个对话框时应用程序变慢,当对话框完成时速度会上升。

其中一个Spinners真的很“重”,它包含60个元素,由一张图片和一个TextView组成。图片(ImageView)很小,但原图是512x512 PNG 12,54kB(这样大吗?)。

一个ArralyList(用于小微调器)直接初始化,小的在应用程序启动时初始化。

这是警报对话框

public class dialog_CardWithdrawRequest extends AppCompatDialogFragment {
private static final String TAG = "dialog_CardWithdrawRequ";

private ArrayList<obj_PrintState> printStatesList;
private Spinner sp_DialogCardWithdrawRequest_Printer;

private Spinner sp_DialogCardWithdrawRequest_Country;
private sendChoosenCountryAndPrintState listener;

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    
    try {
        listener = (dialog_CardWithdrawRequest.sendChoosenCountryAndPrintState) context;
    } catch (ClassCastException e) {
        throw new ClassCastException(context.toString() +
                " must implement sendChoosenCountryAndPrintState listener");
    }
}

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    initArrays();
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.AlertDialogTheme);
    LayoutInflater inflater = getActivity().getLayoutInflater();
    View view = inflater.inflate(R.layout.dialog_cardwithdrawrequest, null);
    
    final int Driver;
    final int iCurrentDriverPosition;
    Bundle receivingBundle = this.getArguments();
    if(receivingBundle != null){
        Driver = receivingBundle.getInt("Driver");
        iCurrentDriverPosition = receivingBundle.getInt("CurrentCountryPosition");
    }else{
        Driver = INT_DEFAULT_VALUE;
        iCurrentDriverPosition =0;
    }
    
    builder.setView(view)
            .setTitle(R.string.dialog_CardWithdrawRequest_Title);
    
    builder.setNegativeButton(R.string.Cancle, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialogInterface, int i) {
        
        }
    });
    
    builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialogInterface, int i) {
            obj_Country selectedCountry = (obj_Country) sp_DialogCardWithdrawRequest_Country.getSelectedItem();
            String sSelectedCountry = selectedCountry.getsHexCountryCode();
            
            obj_PrintState selectedPrintState = (obj_PrintState) sp_DialogCardWithdrawRequest_Printer.getSelectedItem();
            String sSelectedPrintRequest = selectedPrintState.getsPrinterRequestHex();
            
            listener.choosenCountryAndPrintState(sSelectedCountry, sSelectedPrintRequest, Driver);
            
        }
    });
    sp_DialogCardWithdrawRequest_Country = view.findViewById(R.id.sp_DialogCardWithdrawRequest_Country);
    sp_DialogCardWithdrawRequest_Printer = view.findViewById(R.id.sp_DialogCardWithdrawRequest_Printer);
    
    adapter_Spinner_Country adapterCountry = new adapter_Spinner_Country(getContext(), objCountryList);
    adapter_Spinner_Printer adapterPrinter = new adapter_Spinner_Printer(getContext(), printStatesList);
    
    sp_DialogCardWithdrawRequest_Country.setAdapter(adapterCountry);
    sp_DialogCardWithdrawRequest_Printer.setAdapter(adapterPrinter);
    
    sp_DialogCardWithdrawRequest_Country.setSelection(iCurrentDriverPosition);
    return builder.create();
}

    private void initArrays(){
        printStatesList = new ArrayList<>();
        printStatesList.add(new obj_PrintState(PRINTREQUEST_NONE, getText(R.string.dialog_CardWithdrawRequest_PrintRequest_None).toString()));
        printStatesList.add(new obj_PrintState(PRINTREQUEST_UTC, getText(R.string.dialog_CardWithdrawRequest_PrintRequest_UTC).toString()));
        printStatesList.add(new obj_PrintState(PRINTREQUEST_LOCAL, getText(R.string.dialog_CardWithdrawRequest_PrintRequest_Local).toString()));
    }
    
public interface sendChoosenCountryAndPrintState{
    void choosenCountryAndPrintState(String sSelectedCountry, String sSelectedPrintRequest, int Driver);
}

}

这是来自mainActivity的调用

helperThread = new HandlerThread("HelperThread");
    helperThread.start();
    Handler helperHandler = new Handler(helperThread.getLooper());
    
   helperHandler.post(new Runnable() {
        @Override
        public void run() {
            dialog_CardWithdrawRequest dialog_cardWithdrawRequest = new dialog_CardWithdrawRequest();
            Bundle information = new Bundle();
            information.putInt("Driver", iDriver);
            information.putInt("CurrentCountryPosition", finalIPosition);
            dialog_cardWithdrawRequest.setArguments(information);
            dialog_cardWithdrawRequest.show(getSupportFragmentManager(),"CardWithdrawRequest");
        }
   });

如您所见,我已经尝试 post 在不同的线程上进行这种“艰苦的工作”,但我认为 AlertDialog 总是在 UI 线程中运行,我不知道不知道。

我也试过用:

runOnUiThread(new Runnable() {
        @Override
        public void run() {
        
        }
    });

... 512x512 PNG 12,54kB (is this to large?) ... 是的,是的。

考虑到解压后的原始位图是 x * y * 4 字节(R、G、B 和 A 分量,每个分量占 1 个完整字节)。
因此,您的每个图像在内存中占 1 MB。

顺便说一下,不需要使用 ImageView:只需将图像设置为 TextView 中的复合可绘制对象并挤出一些性能。

这是一个有趣的 link:
https://antonioleiva.com/textview_power_drawables/