Status Update
Comments
ng...@gmail.com <ng...@gmail.com> #2
We are currently using AGP internal task types to flag memory-intensive tasks to enforce a reduced parallelism at execution time. I've raised this separately (with a lot more detail) as a feature request (
al...@android.com <al...@android.com>
cy...@gmail.com <cy...@gmail.com> #4
Another use case that we have is to reactively respond to the creation of APKs and AABs. The new AGP APIs allow us to connect out tasks into the artifact pipeline via wiredWith
but the best we can come up with to receive the completed artifact is to wire in toTransform
. This A) does not guarantee that we will receive the final artifact as more transforms may be applied after our task is called, and B) requires us to copy the input property file/dir to our tasks output property file/dir in order to not break the build cache.
The reactive behavior of the above is the complicating factor.
A non-reactive approach could simply depend upon the task name and then look for a hardcoded path in the build directory (which is still sort of gross, since the build output paths are not documented as public API and change from time to time).
Another approach would be to wire a custom task to consume the output of the build via the built artifacts loader feeding an input property. However, this approach cannot be applied reactively. Either the custom task is included in the build and causes the creation of the binary artifact, or it is not included in the build and never gets invoked.
cy...@gmail.com <cy...@gmail.com> #6
We didn't provide a task wiring helper for that case as there's only one thing to wire, but I can see how the inconsistency can be misleading
cy...@gmail.com <cy...@gmail.com> #7
WRT variant.artifacts.get(SingleArtifact.APK))
, if the task is included in the build it will cause the creation of the artifact. Our build is currently defined to reactively perform some actions (predominantly some fancy reporting) only if work is actually performed.
We had previously been pushing our build to wire in to task outputs by locating tasks by type and referencing output properties as inputs to tasks registered via task finalizes
or dependsOn
relationships. This started getting more and more fragile as the AGP APIs migration proceeded/matured. I'm to the point now where I think the notion of reactive execution is hostile to the direction/expectations of both Gradle and AGP and want to start moving away from it, yet our build as it currently stands does rely on this behavior.
I bring up this up as a gap only because I don't know if I'll be able to completely refactor our CI pipeline's expectations in time for Gradle 8+.
ch...@google.com <ch...@google.com> #8
al...@android.com <al...@android.com> #9
Another minor functionality gap: We have a build that has test coverage enabled during test execution but then we manually disable the coverage report generation for all project modules as we have a custom coverage report task that creates an aggregate test coverage report for the entire project. This saves us the execution time, I/O, and protects us from Jacoco implementation instabilities.
We're currently using the following to accomplish this:
project.tasks.withType(JacocoReportTask::class.java) {
enabled = false
}
Description
Process: ngvl.android.appdialogfragmentissue, PID: 9331
android.util.AndroidRuntimeException: Window feature must be requested before adding content
at android.support.v7.app.AppCompatDelegateImplV7.throwFeatureRequestIfSubDecorInstalled(AppCompatDelegateImplV7.java:1675)
at android.support.v7.app.AppCompatDelegateImplV7.requestWindowFeature(AppCompatDelegateImplV7.java:581)
at android.support.v7.app.AppCompatDialog.supportRequestWindowFeature(AppCompatDialog.java:137)
at android.support.v7.app.AlertController.installContent(AlertController.java:211)
at android.support.v7.app.AlertDialog.onCreate(AlertDialog.java:256)
at android.app.Dialog.dispatchOnCreate(Dialog.java:395)
at android.app.Dialog.show(Dialog.java:296)
at android.support.v4.app.DialogFragment.onStart(DialogFragment.java:406)
at android.support.v4.app.Fragment.performStart(Fragment.java:2000)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1102)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1617)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:517)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5849)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:763)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:653)
Library used:
com.android.support:appcompat-v7:23.2.1
com.android.support:design:23.2.1
com.android.support:support-v4:23.2.1
Theme used:
Please, see attached project. It's a simple new project in Android Studio using "Basic Activity".
Devices/Android versions reproduced on:
Nexus X emulator (Android N preview)
Asus Zenfone 2 (Android 5.0)
Nexus 5 (Android 6.0.1)
- Relevant code to trigger the issue.
----------------------------------------------------------------------
I would like to use the fragment below both in a layout and as a dialog.
----------------------------------------------------------------------
public class MyFragment extends AppCompatDialogFragment {
private static final String EXTRA_SHOW_AS_DIALOG = "dialog";
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = getArguments();
boolean showAsDialog;
if (args !=null){
showAsDialog = args.getBoolean(EXTRA_SHOW_AS_DIALOG, false);
setShowsDialog(showAsDialog);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
String[] items = new String[]{ "one", "two", "three" };
View root = inflater.inflate(R.layout.fragment_my, container, false);
ListView listView = (ListView)root.findViewById(R.id.list);
listView.setAdapter(new ArrayAdapter<>(getActivity(), android.R.layout.simple_list_item_1, items));
return root;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// I think the issue is here.
return new AlertDialog.Builder(getContext())
.setTitle("Choose a number")
.setPositiveButton("OK", null)
.create();
// Using the code below, it works, but I want to add the negative button...
// Dialog dialog = super.onCreateDialog(savedInstanceState);
// dialog.setTitle("Choose a number");
// return dialog;
}
public static MyFragment newInstance(boolean b) {
Bundle args = new Bundle();
args.putBoolean(EXTRA_SHOW_AS_DIALOG, b);
MyFragment f = new MyFragment();
f.setArguments(args);
return f;
}
}
-----------------------------------------------------------------------------
Calling it from an activity, the issue happens.
-----------------------------------------------------------------------------
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
assert fab != null;
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
MyFragment.newInstance(true).show(getSupportFragmentManager(), "dialog");
}
});
}
}