it depends on the features you want to use (and their datatypes).
In the Docs it says:
One-hot encoding maps a categorical feature, represented as a label index, to a binary vector with at most a single one-value
This means that:
if your categorical feature is already "represented as a label index", you don't need to use
StringIndexer first. Instead, you can directly apply one-hot encoding.
On the other hand:
if your categorical feature is, e.g. represented as string values, it becomes necessary to use
StringIndexer first to convert the string values into label indices (numeric values).
In the example from the OneHotEncoder-Docs you can see that the
DataFrame that is being created already has features of
DoubleType and thus
StringIndexer is not applied before one-hot encoding.